C # 2.0 specification (Generics IV)

Source: Internet
Author: User
Tags modifiers

Connect generic Three

20.6 Generic methods

A generic method is a method that is related to a particular type. In addition to the general parameters, the generic method also names a set of type parameters that you need to provide when using the method. Generic methods can be declared in class, struct, or interface declarations, and they can themselves be generic or non-generic. If a generic method is declared in a generic type declaration, the method body can reference the type parameter of the method and the type parameter that contains the declaration.

class-member-declaration: (class member declaration:) ... generic-method-declaration (generic method declaration) Struct-member-declaration: (struct-member-declaration:) ... generic-method-declaration (generic method declaration) Interface-member-declaration: (Interface member declaration:) ... interface-generic-method-declaration (interface generic method declaration) the Declaration of a generic method is implemented by placing a type parameter list after the name of the method. Generic-method-declaration: (generic method declaration:) Generic-method-header Method-body (Generic method Header method body) Generic-method-header: (generic method header:) 

attributes opt method-modifiers opt return-type member-name type-parameter-list (formal-parameter-list opt) Type-parameter-constraints-clause opt
(attribute optional method modifier Optional return type member name type parameter list (formal parameter list optional) type parameter constraint statement optional)
Interface-generic-method-declaration: (interface generic method declaration:)
attributes opt new opt return-type identifier type-parameter-list
(formal-parameter-list opt) type-parameter-constraints-clauses opt;
(attribute optional new optional return type identifier type parameter list (formal parameter list optional) type parameter constraint statement optional;
Type parameter lists and type parameter constraint statements have the same syntax and functionality as generic type declarations. Type parameter scopes declared by the type parameter list are scoped throughout the generic method declaration and can be used to form a constraint statement that includes a return value, a method body, and a type parameter, but does not include an attribute.

The name of the type parameter of the method cannot be the same as the regular parameter name of the same method.

The following example finds the first element in the array and exists if the given test delegate is satisfied. Generic delegates are described in § 20.4.

Public delegate bool Test<t> (T Item);p ublic class Finder{public static T find<t> (t[] items, test<t> tes T) {foreach (t item in items) {if (Test (item)) return item;} throw new InvalidOperationException ("Item not Found");}}

Generic methods cannot be declared as extern. All other modifiers are valid on a generic method.

20.6.1 generic method signatures

For the purpose of comparing signatures, any type parameter constraint is ignored, like the name of a type parameter, but the number of type arguments is the corresponding, like the position of the element from left to right of the type parameter. The following example shows the method signature under the influence of this rule.

Class A{}class B {}interface ix{t f1<t> (t[] A, int i);//error because the return type and type parameter name are irrelevant, void f1<u> (u[] A, int i);//Both Declarations have the same signature void F2<t><int x>; OK, the number of type parameters is part of the signature void F2 (int x), void f3<t> (T t) where t:a//error, constraint not in the signature considered column void f3<t> (T t) where T:B:}

The overloads of a generic method are further constrained by a rule that is similar to the administrative method overload in the generic type declaration (§20.1.8). Two generic method declarations that use the same name and the same number of type arguments cannot have parameter types for the list of enclosing type arguments when they produce two methods with the same signature in the same order, when they are applied to two methods in the same order. Because this rule constraint will not be considered. For example

Class x<t>{void f<u> (T T, u u) {...}//error, X<INT>. F<int> produces two methods with the same signature void f<u> (U u, t t) {...}//}

20.6.2 Virtual Generic method

Generic methods can be declared using the abstract,virtual and override modifiers. When matching method overrides and interface implementations, a signature that matches the rules described in §20.6.1 is used. When a generic method overrides a generic method declared in a base class, or implements a method in the base interface, the constraint given for each type parameter must be the same in two declarations, where the method type parameter is identified by the original position from left to right.
Abstract class Base

{public abstract T f<t,u> (T T, u u);p ublic abstract T g<t> (T T) where t:icomparable;} Class Derived:base{public override x f<x,y> (x x, y y) {...}//okpublic override T g<t> (T t) {...}//Error}

The rewrite of F is correct, because the type parameter names are allowed differently. The rewrite of G is wrong because the given type parameter constraint (where there is no constraint) does not match the overridden method.

20.6.3 calling a generic method

Generic method calls can explicitly specify a type argument list, or omit a type argument list, and rely on type inference to determine type arguments. The exact compile-time processing of a method invocation, including generic method calls, is described in §20.9.5. When a generic method does not use a type argument list invocation, type inference is performed as described in §20.6.4.

The following example shows how overload resolution occurs when type inference and type arguments override the argument list.

Class test{static void f<t> (int x, T y) {Console.WriteLine ("One");} static void F<t> (T x, long y) {Console.WriteLine ("a");} static void Main () {f<int> (5,324),//ok, print "One" f<byte> (5,324),//ok, print "One" f<double> (5,324);//Error, Fuzzy f (5,324); OK, print "one" F (5,324l); Error, ambiguous}}

20.6.4 type argument inference

When a generic method is called without specifying a type argument, type inference (types inference) processing attempts to infer the type argument for the call. The existence of type inference allows for a more convenient syntax when calling a generic method, and prevents programmers from specifying redundant type information. For example, given a method declaration

Class util{static Random rand = new Random (), static public T choose<t> (t first, T second) {return (rand. Next (2) = = 0)? First:second}}

It is also possible to call the Choose method without explicitly specifying a type argument.

int i = Util.choose (5,123); Call choose<int>string s = util.choose ("foo", "Bar");//Call choose<string>

With type inference, type argument int and string are determined by the method's arguments.

Type inference occurs as part of a method invocation (§20.9.5) compile-time process, and occurs before an overload decision is invoked. When a particular method group is specified in a method call, the type arguments are not specified as part of the method invocation, and type inference is applied to each generic method in the method group. If the type inference succeeds, the inferred type real arguments is used to determine the argument type of the subsequent overload decision. If overload resolution chooses the generic method that will be called, the inferred type real arguments is used as the actual type argument of the call. If a particular method type inference fails, this method will not participate in overload resolution. A type inference failure itself will not produce a compile-time error. However, when overload resolution fails to find the applicable method, it causes a compile-time error.

If the number of arguments supplied differs from the number of parameters of the method, the inference will fail immediately. Otherwise, type inference takes place independently for each formal argument that is provided to the method. Assume that this argument is of type A and that the corresponding argument is type P. Type inference associates type A and p by following these steps.

If any of the following is true, nothing can be inferred from the argument (but the type inference is successful).

-P is independent of any type parameter of the method [1]
-argument is a null character
-The argument is an anonymous method
-an argument is a method group



If P is an array type and a is an array type of rank, then replace A and p with the element type A and p, and repeat this step.

If P is an array type, and a is an array type of a different rank, the type inference for the generic method fails.

If P is the type parameter of the method, the type inference succeeds for that argument, and a is the type inferred by that type argument.

Otherwise, p must be a constructed type. If the MX, for each method type parameter that appears in P, can determine exactly one type of TX, replacing each MX with each TX, which produces a type that, for this type, can be converted by a standard implicit conversion, the type inference for this argument succeeds for each MX,TX is the inferred type. Method type parameter constraints, if any, because the reason for type inference is ignored. If there is no TX presence or more than one TX for a given MX, then the generic method's type inference will fail (more than one TX presence may occur, p is a generic interface type, and a implements multiple constructed versions of the interface).

If all the method arguments are processed through the previous algorithm, then all inferences from the actual argument will be aggregated. This set of inferences must have the following attributes.

Each type parameter of a method must have a type argument that is inferred for it. In short, this set of inferences must be complete ([/b]complete[/b]) [/b];

If a type parameter occurs more than once, then all inferences to that type parameter must infer the same type argument. In short, this set of interfaces must be consistent ([/b]consistent[/b]) [/b].


If a complete and consistent set of inferred type arguments can be found, then for a given generic method and argument list, type inference can be said to be successful.

If a generic method uses a parameter array (§10.5.1.4) declaration, then type inference is performed on the method in its usual way. If the type inference succeeds and the resulting method is available, then the method is feasible in its usual form for overload resolution. Otherwise, type inference is performed on the extended form of the method (§7.4.2.1).

[1] That is, p is not one of the types listed in the method's type parameter list.

The above is C # 2.0 specification (generic four) content, more relevant content please pay attention to topic.alibabacloud.com (www.php.cn)!

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.