Equipment five
20.8 Expression and statements
Some expressions and statements have been modified for generics. This section will introduce these changes.
20.8.1 Default Value Expression
Defaults are used to get a type of default (§5.2). Usually a default expression is used for type parameters because if the type parameters are a value type or reference type, it may not be already. (There is no conversion from NULL type to type parameters.)
PRIMARY-NO-ARRAY-CREATION-Expression: (Basic countless group creation expressions :)
...
DEFAULT-VALUE-EXPRESSION (default expression)
Default-value-expression :( Default value expression :)
Primary-expression. Default (basic expression .default)
Predefined-type. default (predefined type. Default)
If a basic expression is used in a default expression, and this basic expression cannot be divided into a type, then a compile time error will occur. However, the rules described in § 7.5.4.1 are also suitable for forming E.DEFAULT.
If the default value of the default expression is calculated at runtime for a reference type, the result is to convert NULL to that type. If the default value of the default expression is calculated at runtime for a value type, the result is the default value of the value type (§4.1.2).
If the type is a reference type or type parameter with a class constraint, the default value expression is a constant expression (§ 7.15). In addition, if the type is one of the following values, the default value expression is a constant expression: Sbyte, Byte, Short, Ushort, Int, Uint, long, ulong, char, float, double, decimal, or bool.
20.8.2 Object Creating an expression
Types of object common expressions can be a type parameter. When the type parameter is specified as a type of expression in an object, the following two conditions must have, otherwise the compile error will occur.
The list of real parameters must delete the constructor constraints that must be specified for the type parameters.
You can perform an object to create an expression by creating an instance of the runtime type that is bound to. The runtime type can be a reference or value type.
20.8.3 Operator Type
The TypeOf operator can be used for type parameters. The result is the system.type object that is bound to the runtime type of the type parameter. The TypeOf operator can also be used for constructive types.
Class x
{
Public static void prinTtypes ()
{
Console.writeline (TypeOf (T) .fullname;
Console.writeLine (TypeOf (x
}
}
Class M
{
Static void main ()
{
X
}
}
The previous program will print as follows.
System.Int32
X
The TypeOf operator cannot be used for the name of the generic type declaration of the specified type.
Class x
Class M
{
Static void main ()
{
TYPE T = TypeOf (x); // error, x needs type
}
}
20.8.4 Reference equality operator
If t is constrained by a class constraint, the reference type equal operator can be used to compare the value of the type parameter T.
The usage of the reference type equal operator can make the field parameters of the type parameter T easily compare with other NULL-based arguments, even if T has no class constraints. At runtime, if T is a value type, the result of the comparison will be false. The following example checks if the argument of a non-constraint type parameter type is NULL.
Class C
{
Void f (t x)
{
IF (x == null) thow new argumentnullexception ();
...
}
}
Even t can also represent a value type, the x == NULL member is also allowed, and when T is the value type, the result is simple to define as false.
20.8.5 IS operator
The IS operator operation on the open type follows the usual rules (§7.9.9). If the E or T type is a open type, the dynamic type check is always performed on E and T at runtime.
20.8.6AS operator
As long as T has a class constraint, the type parameter T can be used on the right of the AS operator. This limitation is required because the value NULL may be returned as the result of the operator.
Class X
{
Public T f
{
Return O as t; // ok, t has a class constraint
}
Public T g
{
Return o as t; / / error, t is not constrained
}
}
In the current specification of the AS operator (§7.9.10), the last point for expression E AS T indicates that if the type of compiles from E, there is no effective explicit reference conversion, there will be compile errors. . For generics, this rule is slightly modified. If the compilation type or T is an open type, in this case, the compile error will not occur; the inspection will be executed when the runtime check will be executed.
20.8.7 Abnormal statement
For open types, THROW (8.9.5) and TRY (§8.10) usual rules are applicable.
As long as the type parameters have the system.exeption exception (or subclass) as class constraints, the throw statement can be used as a type of expression given by a type of parameter. As long as the type parameter system.exception is constrained as a class constraint, the type of naming in the CATCH statement may be a type parameter.
20.8.8 LOCK statement
The LOCK statement can be used as an expression given by a type of parameters. If the runtime type of the expression is a value type, Lock will have no effect (because there is no other reference for the packing value).
20.8.9 Using statement
Using statements (§8.13) Follow the usual rules: Expressions must be implicitly converted to System.idisposable. If the type parameter is constrained by system.idisposable, then this type of expression can use the USING statement.
20.8.10 Foreach statement
A foreach statement given in the following form
Foreach (ElementType Element In Collection) Statement
If the collection expression is a type that does not implement the collection mode, the constructor interface system.collections.generic.ienumerable
IENUMERATOR
Try
{
Where (enumerator.movenext ()) {
ElementType Element = (ElementType) enumerator.current;
STATEMENT;
}
}
Finally {
ENUMERATOR.DISPOSE ();
}
20.9 Find Rules Revised
The generic modification certain basic rules used to find and bind the name. The following sections re-describe all basic name lookup rules in consideration of generics.
20.9.1 Namespace and Type Name
Alternative §3.8 is replaced as follows.
There are several contexts in the C # program to specify namespaces or type names. Any form of name can be composed of one or more identifier symbols separated by ".".
Namespace-name: (Name Space Name :)
Namespace-or-type-name (namespace or type name)
Type-name: (Type name :)
Namespace-or-type-name (namespace or type name)
Namespace-or-type-name: (Name Space or Type :)
Identifier Type-Argument-List Opt (Identifier Type II list)
Namespace-or-type-name. Identifier type-argument-list Opt (Namespace or Type name. Identifier type real parameter list options)
The namespace name is a reference naming name or type name (Namespace-or-type-name). See the decisions described below, namespaces or type names of the namespace name must reference a namespace, otherwise the compile time error occurs. There is no type inform in a namespace name (only types can have types).
Type names are named space or type names of reference types (Namespace-or-type-name). See the decisions described below, the namespace or type name of the type name must reference a type, otherwise the compile time error occurs.
The meaning of namespace or type name is determined as follows.
If the namespace or type name is in the form of i or i
-
If the namespace or type name appears within the generic method declaration, and the declaration includes a type parameter that is not specified by I a given name, the name of the name is referenced by the namespace or type name.
-
Otherwise, if the namespace or type name appears within the type declaration, for each instance of the type T (
U
If you do not specify a declaration that contains a given name of I, and there is no type of parameter t, the name of the name, the name of the name is referenced.
U
Otherwise, if i is the name of the member to access the member, and if that member is a type with the number of match type parameters, the namespace or type name reference type T.i or type T.I
-
Otherwise, for each namespace N in the namespace that appears in namespace or type name, and continue to use each closed namespace (if any), then end with the global namespace, the following steps will be Calculate until the entity is positioned. U
If i is the name in the namespace in n, and does not specify a list of types, then the namespace or type name references the namespace.
U
Otherwise, if i is the name of the accessible type with the number of match type parameters in n, then the namespace or type name references the type constructed using a given type.
U
Otherwise, if the location of the namespace or type name appears, the namespace declaration is closed by n
- If the namespace declaration contains a USING alignname instruction by I given the name, I has an import namespace or type, and no specified parameter list, then the namespace or type name references the namespace or type.
- Otherwise, if the namespace of the using namespace indicator is imported by the namespace, there is a type of matching type, the number of matching type parameters with I, then the namespace or type name reference is constructed by a given type This type.
- Otherwise, if the namespace imported by the namespace declared, the namespace imported contains multiple types of g a given name, matching type parameters, then named space or type name is blurred, and will result in errors .
-
Otherwise, namespace or type name is undefined and error occurred while compiling.
l
Otherwise, namespace or type name is Ni or Ni
-
If n references a namespace and if i is the namespace name embedded in N, and there is no specified type real parameter list, the namespace or type name references the embedded namespace.
-
Otherwise, if n references a namespace, and i is the name of the accessible type with the number of match type parameters, then the namespace or type name references the type constructed by a given type.
-
Otherwise, if n reference classes or struct types, and i is the name of the accessible type in N with the N-type parameters, then the namespace or type name is referenced by the type constructed by the token.
-
Otherwise, N.I is an invalid namespace name and the compile time error will occur.
20.9.2 Member Find
The following can be replaced §7.3
Members Finding is a process of determining types based on the meaning in context. In an expression, the member lookup can appear as a simple name or member access (§20.9.4).
The member lookup of the name N in Type T is determined as follows.
First, a set of accessible members named N is determined.
-
If T is a type parameter, the type specified by each class constraint or interface constraint as T, and the collection is a joint accessible member of the named member with the N named member of the Object.
-
Otherwise, this collection is composed of all Named members in T, including inheritance members, and naming members who are named in Object. If T is a constructive type, the collection of members is obtained by replacing the type of the type described in §20.5.4. Members including Override modifiers will be discharged from the collection.
Next, members hidden through other members will be removed from this collection. For each member S.m, S is the type where M is declared, the following rules can be applied.
-
If m is a constant, field, attribute, event, or enumeration member, the members declared in all base classes of S will be deleted from this collection.
-
If m is a type declaration, all non-type declarations in the base class are deleted from the collection, and all the type declarations of the same number type parameters as the S in the base type, will be Remove it in this collection.
-
If m is a method, all non-way members declared in the base class of S are deleted from this collection, and all methods that are the same signature as the M in the base type, will be from this Remove it in the collection.
Next, the interface members hidden through class members will be removed from the collection. This step, only when t is a type of parameters, and T is valid when t has class constraints and multiple interface constraints. For each member S.m in the collection, S is M in which the rule is applied if S is a class declaration rather than Object.
-
If m is a constant, field, attribute, event, enumeration member, or type declaration, all members declared in the interface declaration will be removed from this collection.
-
If m is a method, all non-way members declared in the interface type will be deleted from this collection, and all methods that are the same signature as the M in the interface will be removed from this collection. .
Finally, after deleting hidden members, the results of the lookup will be determined
-
If the collection consists of a single member, it is not type, method, then this member is the result of the lookup.
-
Otherwise, if the collection only contains the method, then this group method is the result of the lookup.
-
Otherwise, if the collection contains only the type declaration, then this set of type declares in the result of the member lookup.
-
Otherwise, lookup is unclear, and the compile time will occur.
For type instead of type parameters and members of the interface, the member lookup in the interface is a strict single inheritance (each interface in the inheritance is just zero or a direct base interface), and the effect of finding the rules Just derived members hide the base class members with the same name and signature. This single inheritance look is clear. The possible fuzzality in the member looks from the multiple inheritance interfaces described in §13.2.5
20.9.3 Simple name
Alternative § 7.5.2 is replaced as follows.
Simple names are followed by an identifier, followed by a list of optional type parameters.
Simple-name: (simple name :)
Identifier Type-Argument-List Opt (Identifier Type II list)
For i or i
If the simple name appears in the block, and if the local variable declaration space of the block contains local variables or parameters of a given name given by i, this simple name references the local variable and parameters and is classified as a variable. If the type real parameter list is specified, the compile time error will occur. If the simple name appears within the generic method declare, and if the declaration contains the type parameters given by I given the name of the name, the simple name references that type parameter, if only the type of real-name list is compiled, error. Otherwise, each instance of the type T of the type T directly closed, structural, or enumeration declarations, continues to use an instance type (if any) of each enclosed external class or structure declaration.
-
If the declaration of T includes a type parameter given by I given a name, the simple name references the type parameters. If the type real parameter list is specified, the compile time error will occur.
-
Otherwise, if you find a match if the member of T in T
U
If t is an instance type of the class or structure type, and looks for one or more methods, the result will be a method group associated with the THIS expression. If the type real parameter is specified, it is used in a generic method call (20.6.3). U
If T is an instance type of the type or structure type, if you find an instance member, and the reference appears within a block of an instance constructor, an instance method, or an instance accessor, its results will be in the form of this.i. Member access is similar. If the type is specified, the compile time error will occur.
U
Otherwise, the result is similar to those in T.I or T.I
Otherwise, for the namespace N of the namespace with each simple name appears, continue to use each closed namespace (if any), and end with the global namespace, the following steps will be calculated until one The entity is positioned.
-
If i is the name of a namespace in n, and does not specify a list of types of references, the simple name will reference the namespace.
-
Otherwise, if i is the name of an accessible type in N with a number of match type parameters, the simple type references the type constructed by a given type.
U
If the namespace declaration contains an associated Using alias command, i is an imported namespace or type, and does not specify a type real-name list, then a simple name references the namespace or type.
U
Otherwise, if the namespace declared by the namespace declaration, the namespace is imported, and it is only a type of given name, matching type parameters, then simple name references the type constructed by a given type.
U
Otherwise, if the namespace declared by the namespace declaration, the namespaces are imported, including a number of given names, matching type parameters, then simple names are unclear, will result in errors when compiling
l
Otherwise, the name given by simple names is undefined, which will result in errors when compiling.
20.9.4 Member Access
The following can be replaced with §7.5.4.
Members Access consists of a basic expression or a predefined type, a "." Tag, and then the identifier, and then the optional type real parameter list.
MEMBER-Access: (Member Access :)
PRIMARY-Expression. Identifier Type-Argument-List Opt (Basic Expression. Identifier Type II list list optional)
PREDEFINED-TYPE. Identifier Type-Argument-List Opt (Predefined Type. Identifier Type Resistant List Optional) Predefined Type: One of the following
Bool BYTE CHAR DECIMAL DOUBLE FLOAT INT Long
Object Sbyte Short String uint Ulong Ushort
For members of EI or EI
If e is a namespace, i is the name of none of nature, and does not specify the type of arguments, then the result is this namespace. If e is a namespace, i is the name of the name of the type, the number of E-match type parameters, then the result is a type constructed by a given type. If e is a predefined type or a basic expression classified as a type, if the E is not a type parameter, and if the member lookup generated in E, E.I is calculated and calculated as follows. -
If i identifies one or more types declarations, then use the same number (possibly zero) type parameters to determine the type declaration, just as it is provided in the type of field. The result is a type constructed by a given type. If the type declaration does not match the number of type parameters, the compile error will occur.
-
If i identifies one or more methods, the result is a method group that does not have an associated instance expression. If the type real parameter is specified, it will be used in the generic method call (§20.6.3).
-
If i identifies a static property, static fields, static events, constants, or an enumeration member, and if the type real parameter is specified, the compile time error will occur.
-
If i identifies a static property, the result is an attribute access to an associated instance expression.
-
If i identifies a static field
U
If the field is read-only, the fields will be declared here in addition to the static constructor of the class or structure. The result is a value, that is, the value of the Static field I in E.
U
Otherwise, the result is a variable, that is, the static field I in E.
-
If i identifies a static event
U
If the reference occurs in a class or structure that is declared in the event, and the event is declared (10.7) (10.7), E.I is as if I is a static field.
U
Otherwise, the result is an event access to an unrelated instance expression.
-
If i identifies a constant, then the result is a value, that is, the value of the constant.
-
If i identifies a enumerated member, then the result is a value, that is, the value of enumeration members.
-
Otherwise, E.I is an invalid member reference and will result in compile time errors.
If E is an attribute access, an indexer access, a variable, or a value, which is T, and the member lookup generated in T in T, then E.I is calculated and classified as follows.
-
First, if e is an attribute or index access, the value of the attribute or index accessed (7.1.1) will be obtained, and E is reselected as a value.
-
If i identifies one or more methods, then the result is a method group with an instance expression with associated E. If the type real parameter is specified, it will be used in the generic method call (§20.6.3).
-
If i identifies an instance attribute, instance field, or instance event, and if the type real parameter is specified, the compile time is generated.
-
If i identifies an instance attribute, the result is an instance expression with an associated E.
-
If T is a class type and i identifies an instance field of a class type
U
If the value of E is null, then System.NullReferenceException will be thrown.
U
Otherwise, if this field is read-only, and references the instance constructor of the class that appears in the field declaration, then the result is a value, that is, the value of I references to the object.
U
Otherwise, the result is a variable, that is, the field I referenced by the object.
-
If T is a struct type, and i identifies the instance field U
If e is a value, or if the field is read-only, and references the example structure of the structure that appears in the field declaration, the result is a value, that is, the value of the field i in the e-given structure instance.
U
Otherwise, the result is a variable, that is, the field I in the e a given structure instance;
-
If i identifies an instance event
U
If the reference appears within the class or structure being declared, and the event is declared when the event is declared, E.I is as if I is an instance field.
U
Otherwise, the result is an example expression with an associated E.
Otherwise, E.I is an invalid member reference will result in compile time errors.
20.9.5 Method Call
The following is replaced with the compile time processing section of the method called in §7.5.5.1.
For compilation time processing for M (A) forms, where m is a method group (possibly containing a type of real parameter list), A is an optional reference table, consisting of steps below.
The candidate collection of method calls is constructed. Method F associated with each with method group m
-
If F is non-generic, f is a candidate when F is a candidate.
U
M There is no type of real-name list, and
U
For A (7.4.2.1), f is applicable.
-
If f is a generic, and M does not have a type of real parameter, and F is a candidate when it is established as follows.
U
Type Inference Success (20.6.4), to the list of the type of arguments, and
U
Once the inferred type is replaced, the corresponding method type parameter is replaced, and the parameter list of f is applicable for A, and
U
After replacing the type, the parameter list of f, the non-extensive method that may be declared in the same type in its extended form (7.4.2.1) in its extension form (7.4.2.1) is different.
-
If f is a generic, and M includes a type of real parameter, and f is a candidate when it is established as follows.
U
F and the same number of method type parameters provided in the Type IF list, and
U
Once the type of method type parameters, the parameter list of f, F, is available for A. 7.4.2.1).
The collection of candidate methods is reduced to only a method of derived from depth derived: For each CF method in the collection, C is F in the type declared, all methods declared in the base type of C. Remove it in the collection. If the result of the candidate method is empty, there is no suitable method to exist and the compile time error occurs. If the candidate method is not declared in the same type, the method call will be unclear, and the compile time error will occur (this latter case, only the method in an interface with multiple direct base ports) Call, such as the description of §13.2.5).
The best way for candidate methods collection uses the overload decision rules (§7.4.2). If a single best method cannot be identified, the method call is unclear and generates an error in compile time. When performing an overloaded decision, the parameters of the generic method will be considered after replacing the corresponding method type parameters to type inactor (provided or inferred). The final verification of the best way to be selected
-
Methods are valid in the context of the method group: if the method is a static method, the method group must be accessed from simple names or members through the type source. If this best method is an instance method, the method group must be accessed from a variable or value or base-access, from a simple name or member access. If these needs are not satisfied, the compile error will occur.
-
If the best method is a generic method, the type, or inference) will be checked by a constraint that declares on the generic method. If any type of arguments do not meet the constraints of the corresponding type parameters, a compile time error will be generated. Once the method is selected and verified according to the previous steps, the actual runtime call will be processed according to the function member call rules in §7.4.
20.9.6 Entrusted to create an expression
The following is replaced in §7.5.10.3 to entrust the compile time processing section of the creation of an expression.
For the delegate creation of the form of the New D (E), the D is a delegate type, E is an expression, consisting of steps below.
If e is a method group
-
A single method call will be selected for the method of e (a) form.
U
D 's parameter type and modifier (REF or OUT) is used as a modifier of the real parameter type and the real parameter list A.
U
In the applicable test and type inference, the conversion is not considered. In an implicit conversion, the type requirement is the same.
U
The overload decision step will not be executed. Instead, the collection of candidates must just contain a method with D-compatible methods (followed by replacing the type parameters), and this method will become a newly created principal reference. If there is no matching method, or there is a plurality of matching methods, the compile error will occur.
-
If the method selected is an instance method, the instance expression associated with E determines the delegated target object.
-
The result is a value of D-type, that is, the new creation of the options and target objects.
Otherwise, E is a value of a delegate type
-
D and E must be compatible; otherwise the compile time is incorrect.
-
The result is the value of the D type, that is, a new creation of the same call list like E.
Otherwise, the entrustment creation expression is invalid, and the compile time error occurs.
20.10 right-shang change
Pan types use "<" and ">" character separation type parameters and type untrustworthy (similar to C template syntax). The types of constructs are sometimes nested, such as List
In order to maintain these neutral components, ">>" and ">> =" tags are removed from the lexics, replacing the right shift and right shift assignment.
Operator or punctuation: one
{} [] ().,:;
- * /% & | ^! ~
= <>? - && || == ->
! = <=> = = - = * = / =% = & = | =
^ = << << =
Right-shift: (right shift :)
>>>>
Right-shift-assignment: (right shift assignment)
>> =
Unlike other generated production in syntax, the characters between the right shift and right shift value generated are not allowed to present (even spaces).
The following production is modified by the right shift or right shift assignment.
Shift-expression: (shift expression :)
Additive-Expression Shift-Expression << Additive-Expression (Displacement Expression << Additional Expression)
Shift-expression right-shift addactive-expression (shift expression Right-Shift] Additional expression)
Assignment-Operator: (Assignment Operator :)
=
=
- =
* =
/ =
% =
& =
| =
^ =
<< =
Right-Shift-Assignmentment
Overloadable-binary-operator: (overloaded binary operator :)
-
*
/
%
&
|
^
<<
Right-shift
==
! =
>
<
> =
<=
(Finite)
*****************************
I finally passed this chapter. Hey, your hand is sour, there is a problem, I hope everyone will come out, don't welcome :)