C # 2.0 Specification (generic three)

zhaozj2021-02-16  43

Equipment two

This article is a Microsoft's technical article for translation. For reference for learning C #, please do not use for commercial purposes. http://msdn.microsoft.com/vcsharp/team/language/default.aspx

20.4 Pan-type entrusted statement

The delegate declaration can contain type parameters.

Delegate-Declaration:

Attributes Opt Delegate-Modifiers Op D delegate Return-Type Identifier Type-Parameter-List Opt

(Formal-parameter-list opt) Type-Parameter-Constraints-Clauses Opt;

(Entrusted statement: Features Optional Principal-Decorator Optional Delegate Return Type Identifier Type Parameter List Optional (official parameter list option) Type parameter binding statement options

The delegation of the type parameters declaration is a generic delegation statement. The delegate statement only supports the type parameter constraint statement (§20.7) when supporting the type parameter list (§20.7). In addition to the desired, generic commission declarations and conventional entrustment statements follow the same rules. Each type parameters in the generic delegate declaration define a name in the specific declaration space associated with the delegate (§3.3). The scope of the type parameters in the delegate declaration include the return type, the formal parameter list, and the type parameter constraint statement.

Like other generic type declarations, the type of universal parameters must be given to form a configuration delegate type. The parameters and return values ​​of the delegate type are formed, and each type of parameters corresponding to each type of parameters of the delegate declaration are formed. The result return type and parameter type is used to determine what method is compatible with the constructive type. E.g

Delegate Bool Predicate (T Value)

Class X

{

Static BOOL F (INT I) {...}

STATIC BOOL G (String S) {...}

Static void

Main

() {

Predicate p1 = f;

Predicate P2 = g;

}

}

Note that two assignments equivalent in the previous main method are below a longer form.

Static void

Main

() {

Predicate p1 = new predicate (f);

Predicate P2 = New Predicate (G);

}

Due to the method group conversion, shorter forms are also possible, which is described in §21.9.

20.5 Construction Type

The generic type declaration does not represent a type. Instead, generic type declarations are used as a "blueprint" that forms many different types of "blueprints" by applying types of arguments. The type parameters are written between polarizers and follow the generic type declaration name. Types named using at least one argument are called constructed type. The structure type can be used in most places that can appear in the language 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 (Identifier Type II list option)

Namespace-or-type-name. Identifier (namespace or type name. Identifier)

TYPE-Argument-List Opt (Type IPLES)

The structure type can also be used as a simple name (§20.9.3) in the expression (20.9.4). When a namespace or type name is calculated, only generic types with the correct number of types of parameters will be considered. Thus, as long as the type has a different number of type parameters and declares that the same identifier identifies different types of identifier. This is useful for mixing using generics and non-extensive classes in the same procedure.

Namespace system.collections

{

Class queue {...}

}

Namespace sysem.collections.generic

{

Class Queue {...}

}

Namespace myApplication

{

Using system.collections;

Using system.collections.Generic;

Class X

{

Queue Q1; //system.collections.queue

Queue Q2; // system.collections.Generic.Queue

}

}

Detailed rules for the name lookup in §20.9 in this code. The resolutions in these codes are described in §20.6.5.

Type names may identify a constructive type, although it does not specify type parameters directly. This situation occurs when a type nested in a generic class declaration, and the instance type of the declaration will be implicitly used because the name is found (20.1.2).

Class Outer

{

Public class inner {...}

Public Inner i; // i is Outer .inner

}

In an insecure code, the structure type cannot be used as a non-hosting type (18.2).

20.5.1 Types

Everything in one type parameter list is just a type.

TYPE-Argument-List: (Type Real Parametric List :)

()

TYPE-Arguments: (Type Introduction :)

Type-argument

TYPE-Arguments, Type-Argument (Type-argument, type inform)

TYPE-Argument: (Type Introduction :)

Type

Types can also be constructed or type parameters. In an insecure code (18), type solid parameters cannot be a pointer type. Each type of actor must follow any constraints on the corresponding type parameter (§20.7.1).

20.5.2 Open and Closed Types

All types can be divided into open type or a closed type (CLOSED TYPE). Open type is the type of type parameter. More clear statement is

Type parameters define an open type

The array type is only open type only when its element is an open type.

The structure type only when one or more of the types of arrases is open type, it is open type.

Non-open types are closed types.

At runtime, all code in the generic type declaration is executed in a context of a closed-constructed type, which is created by using the type universal argument to the generic declaration. Each type in the generic type is bound to a specific runtime type. All statements and expressions are typically happened for the closed type, and the open type only occurs when compiling.

Each closed constructed type has its own set of static variables, which are not shared by other closed types. Because there is no open type at runtime, the open type is not associated with static variables. If the two closed constructs are constructed from the same type, and the corresponding type of collent is also the same type, then they are the same type. 20.5.3 Based class and interface of constructive type

Table types have a direct base class, just like a simple type. If the generic class declaration does not specify the base class, its base class is Object. If the base class is specified in the generic class declaration, the base class of the constructed type is obtained by replacing the type of constructive corresponding type of the constructive type by reference to each type of parameters in the base class declaration. Give a genus declaration

Class B {...}

Class G : b {...}

The base class of the structure type G will be B .

Similarly, construct classes, structures, and interface types have a set of explicit basegings. The explicit base interface is formed by accepting an explicit base reference declaration and an alternative in the generic type declaration, which is the corresponding type of parameters that will be in the base reference declaration.

A type of all base classes and basegings are formed by recursively obtain the base class and the interface of the intermediate base class and the interface. For example, give a pivot class declaration

Class a {...}

Class B : a {...}

Class C : B > {...}

Class D : c {...}

The base class of D is C , B >, a, and object.

20.5.4 Members of Construction Types

The non-inherited member of the constructed type is obtained by replacing the type of argument, the type of constructed type of the constructor.

For example, give a pivot class declaration

Class Gen

{

Public t [,], A;

Public Void G (INT I, T T, GEN gt) {...}

Public u prop (Get {...}) set {...}}

Public int h {double d} {...}

}

Construct Type Gen > has the following members.

Public int [,] [] a;

Public Void G (INT I, INT [] T, Gen , int [] gt>) {...}

Public iComparable Prop {Get {...} set {...}}

Public int h (double d) {...}

Note that alternative processing is based on the semantic meaning of the type declaration, is not a simple text-based alternative. The type of member a in the generic class declaration GEN is "two-dimensional array of Ti," thus in the previous instantiated type, the type of member A in the previous instantiation is the "two-dimensional array of INT type" or int [,] [].

The inheritance member of the constructor is obtained in a similar method. All members of the direct base class are already determined. If the base class itself is constructed, this may include the recursive application of the current rule. Then, inheritance members are converted by replacing each type of parameters in the member statement, replacing the constructed type corresponding type.

Class B

{

Public u f (long index) {...}

}

Class D : B

{

PUBLIC T G (String S) {...}

}

In the previous example, the non-inherited member Public INT G (String S) of the constructor type D is obtained by the type INT of the alternative type parameter T. D also has a succession member from class declaration B. This inheritance member is determined by first determining a member of the constructed type B , the determination of the member B is generated by replacing the U to replace T [], generate public t [] f (long index) ). Then the type of primary parameter I replace the type parameter T, generates the inheritance member public int [] f (long index). 20.5.5 Accessibility of Type Types

When constructed type C is accessible, then it is accessible. For example, if the generic type C is public, and all types of parameters T1, ..., TN is also public, the accessibility of constructive type is also public. If one of the type names or types of arguments is Private, the accessibility of the constructor is private. If one of the types of actors, the accessibility is protected, the other is INTERNAL, then the accessibility of the constructor is limited to this class, as well as subclasses within this assembly.

20.5.6 conversion

The structure type follows the same rules as the non-float type (§6). When these rules apply these rules, the base class and interface of the constructor must be determined in the ways described in §20.5.3.

In addition to those described in §6, there is no special conversion between the constructor. In particular, unlike array types, constructive reference types are not allowed to "Co-Variant" conversion. That is, the type List cannot be converted to type list (whether implicit or explicit) is also the same. Similarly, there is no conversion from List to List .

The basic principle for this is very simple: if it can be converted to List , it is clear that you can store a value of a type A to this LIST. This will destroy each object in the List , which is always the value of the value of type B, or when it is assigned to the set class, an unpredictable error will occur.

The behavior of the conversion and the runtime type check is shown below.

Class a {...}

Class B: a {...}

Class colletion {...}

Class List : Collection {...}

Class test

{

Void f ()

{

List Lista = new list ();

List listb = new list ();

Collection C1 = Lista; // OK, List

Collection C2 = Listb; // OK, List is a collection

List a1 = listb; // error, no implicit conversion

List a2 = (list ) listb; // error, no explicit conversion

}

}

20.5.7System.Nullable Type

The generic structure type System.Nullable generic structure type is defined in the .NET base class library, which indicates that a value of a type T can be NULL. System.null Type is useful in many cases, for example, to indicate the accessibility of the data library table, or an optional feature in the XML element.

It can be implicitly converted from a NULL type to any type constructed by system.null type. The result of this conversion is the default value of System.Nullable . That is, you can write NULLABLE x = null.

Nullable y = NULL;

The same is the same below.

Nullable x = nullable .default;

Nullable Y = Nullable .default;

20.5.8 Using an alias directive

Using an alias can be named a closed constructor, but you cannot name a generic type declaration that does not provide type of arguments. E.g

Namespace N1

{

Class a

{

Class B {}

}

Class C {}

}

Namespace N2

{

Using w = n1.a; // error, can not name generic type

Using x = n1.a.b; // error, can not name generic type

Using y = n1.a ; // OK, you can name a closed constructive type

Using z = n1.c; // ok

}

20.5.9 Characteristics

Open types cannot be used anywhere in the characteristics. An enclosed constructed type can be used as a characteristic, but it cannot be used as a characterist name because system.attribute is not possible to be the base class of generic categories.

Class A: Attribute

{

Public a (Type T) {...}

}

Class B : Attribute {} // Error, you can't use Attribute as base class

Class List

{

[A (TypeOf (t))] T t; // error, there is an open type in the characteristics

}

Class X

{

[A (TypeOf (List )] INT X; // OK, Closed Construction Type

[B ] int y; // error, invalid characteristic name

}

转载请注明原文地址:https://www.9cbs.com/read-25900.html

New Post(0)
CopyRight © 2020 All Rights Reserved
Processed: 0.051, SQL: 9