Overview and specific use of generics

Source: Internet
Author: User
Tags uppercase letter

I. Generic overview

Generic classes and generic methods are both reusable , type safe , and efficient , and are not the same as the non-generic classes and methods that correspond to them. Generics are widely used in containers (collections) and in methods for container operations. The. NET Framework 2.0 Class library provides a new namespace System.Collections.Generic that contains some new generic-based container classes.

    1. Variable type parameters of generics: usually T, but can also use any non-keywords and reserved words;

    2. All mutable type T at compile time takes the form of placeholders, all of which are replaced by the actual incoming type at run time;

Second, the advantages of generics

generics provide a solution for the limitations of earlier versions of the common language runtime and the C # language. The generalization of the previous type (generalization) is implemented by the conversion of the type to the global base class System.Object. the ArrayList container class for the. NET Framework base Class Library is an example of this limitation. ArrayList is a handy container class that can store any reference type or value type without needing to change it.

ArrayList list = new ArrayList ();
List. ADD (1);
List. ADD (175.50);
List. ADD ("Hello Kitty");

Double sum = 0;
foreach (int value in list)
{
sum + = value;
}

Disadvantages:

Convenience comes at a price, which requires that any reference type or value type that joins ArrayList be implicitly converted to System.Object. If these elements are value types, they must be boxed when they are added to the list, and then removed when they are retrieved. The operation of type conversion and boxing, unboxing reduces performance, and in the case where large containers must be iterated (iterate), the effects of boxing and unpacking can be significant. Another limitation is the lack of compile-time type checking, and when a ArrayList converts any type to object, it is not possible to prevent errors like Sum+=vlaue in the client code at compile time;

In the generic list<t> container in the System.Collections.Generic namespace, it is also the operation of adding elements to the container, similar to this:

list<int> listint = new list<int> ();
Listint.add (100);
Listint.add (200);
Listint.add (123.112); Compile error
Listint.add ("heel"); Compile error

Double sum = 0;
foreach (int value in list)
{
sum + = value;
}

The only added list<t> syntax in the customer code compared to ArrayList is the type parameter in the declaration and instantiation. The slightly complex return of the code is that the table you create is not only more secure than ArrayList, but also noticeably faster, especially if the elements in the table are value types.

Iii. type parameters of a generic type

In the definition of a generic type or generic method, the type parameter is a placeholder (placeholder), usually an uppercase letter (you can also use any non-keyword and reserved word's name), such as T. Replace T with the data type specified by the customer code when the client code declares and instantiates the variable of that type. A generic class, such as the List<t> class given in generics, cannot be used as a as-is because it is not a true type, but rather a blueprint of a type. To use MYLIST<T>, the customer code must specify a type parameter within the angle brackets to declare and instantiate a constructed type (constructed type). The type parameter for this particular class can be any type recognized by the compiler. You can create any number of constructed type instances, each with a different type parameter, as follows:

list<int> listint = new list<int> ();
list<float> listfloat = new list<float> ();
list<string> liststring = new list<string> ();

Iv. constraints on generic type parameters

Generics provide the following five types of constraints:

Constraints Describe
where t:struct Parameter type must be a value type
where T:class Parameter type must be a reference type
where T:new () The parameter type must have a public parameterless constructor. When used in conjunction with other constraints, the new () constraint must be placed last.
where T: <base Class name> The parameter type must be a specified base type or a subclass derived from the specified base type
where T: <interface name> The parameter type must be an implementation of the specified interface or the specified interface. You can specify constraints on multiple interfaces. Interface constraints can also be generic.

Unrestricted type parameters:

    1. Instances of mutable types cannot be compared using! = and = =, because these operators are not guaranteed to be supported by specific type parameters;

    2. They can be converted to and from System.Object, and can be explicitly converted to any interface type;

    3. can be compared with null. If an unrestricted type parameter is compared to NULL, the result of the comparison is always false when this type parameter is a value type.

no type constraint: when a constraint is a generic type parameter, it is called an untyped constraint (Naked type constraints).

Class list<t>
{
void add<u> (list<u> items) where u:t
{
}
}

In the example above, T in the context of the Add method is an untyped constraint, and T in the context of the list class is an unrestricted type parameter.

Untyped constraints can also be used in the definition of a generic class. Note that the untyped constraint must also be declared in angle brackets along with other type parameters:

Naked type constraint

public class myclass<t,u,v> where t:v

Because the compiler only considers untyped constraints to be inherited from System.Object, generic classes with untyped constraints are of limited use. You can use an untyped constraint on a generic class when you want to force two type parameters to have an inheritance relationship.

V. Generic type

Generic classes encapsulate operations that are not specific to any particular data type. Generic classes are commonly used in container classes, such as linked lists, hash tables, stacks, queues, trees, and so on. Operations in these classes, such as adding and deleting elements to a container, perform almost the same operation regardless of the type of data being stored.

Typically, you create a generic class from an existing concrete class, and each time you change a type to a type parameter until you achieve the best balance of generality and usability. When creating your own generic class, there are a few things to consider:

    • Which types should be generalized as type parameters. The general rule is that the more types are represented by parameters, the greater the flexibility and reusability of the code. Too much generalization can cause code to be difficult for other developers to understand.

    • If there is a constraint, then what kind of constraint does the type parameter require. A good habit is to use the maximum constraints possible, while ensuring that all types that need to be processed are handled. For example, if you know that your generic class is only intended to use reference types, then apply this class's constraints. This prevents inadvertent use of value types, while using the as operator for T, and checking for null references;

    • Place the generic behavior in a base class or in a subclass. A generic class can do a base class. This should also be considered in the design of non-generic classes. Inheritance rules for generic base classes;

    • Whether to implement one or more generic interfaces. For example, to design a class that creates elements in a generic-based container, you might want to implement an icomparable<t> -like interface where T is a parameter to the class.

For a generic class Node<t>, the customer code can either specify a type parameter to create an enclosing constructed type (node<int>) or leave the type parameter unspecified, such as specifying a generic base class to create an open constructed type (node<t>). A generic class can inherit from a concrete class, an enclosing constructed type, or an open constructed type:

Concrete Type
Class Node<t>: Basenode
Closed constructed type
Class Node<t>: basenode<int>
Open constructed type
Class Node<t>: basenode<t>

A concrete class of non-generics can inherit from a closed constructed base class, but not from an open constructed base class. This is because the customer code cannot provide the type parameters required by the base class:

No error.
Class node:basenode<int>
Generates an error.
Class node:basenode<t>

The concrete classes of generics can inherit from an open constructed type. In addition to the type parameters that are common to subclasses, you must specify the type for all type parameters:

Generates an error.
Class node<t>: Basenode<t, u> {...}
Okay.
Class node<t>: Basenode<t, int> {...}

A generic class that inherits from an open struct type must specify the parameter types and constraints:

Class nodeitem<t> where T:icomparable<t>, new () {...}
Class mynodeitem<t>: nodeitem<t> where T:icomparable<t>, new () {...}

Generic types can use multiple types of parameters and constraints:

Class Keytype<k, v> {...}
Class Superkeytype<k, V, u> where U:icomparable<u>, where V:new () {...}

Open structures and closed constructed types can be used as parameters for a method:

void Swap<t> (list<t> list1, list<t> list2) {...}
void Swap (list<int> list1, list<int> list2) {...}

VI. Generic interface

When an interface is specified as a constraint on a type parameter, only the type that implements the interface can be used as a type parameter.

You can specify multiple interfaces as constraints in one type, as follows:

Class stack<t> where T:icomparable<t>, imystack1<t>{}

An interface can define multiple type parameters, as follows:

Idictionary<k,v>

The inheritance rules for interfaces and classes are the same:

Okay.
Imyinterface:ibaseinterface<int>
Okay.
Imyinterface<t>: ibaseinterface<t>
Okay.
Imyinterface<t>: ibaseinterface<int>
Error.
Imyinterface<t>: Ibaseinterface2<t, u>

The concrete class can implement the enclosing construction interface, as follows:

Class myclass:ibaseinterface<string>

A generic class can implement a generic interface or a enclosing construction interface, as long as the parameter list of the class provides all the parameters required by the interface, as follows:

Okay.
Class Myclass<t>: ibaseinterface<t>
Okay.
Class myclass<t>: Ibaseinterface<t, string>

Generic classes, generic structures, and generic interfaces have rules that have the same method overloads.

Vii. generic methods

A generic method is a method that has a reputation for type parameters, as follows:

void swap<t> (ref T LHS, ref t RHS)
{
T temp;
temp = LHS;
LHS = RHS;
RHS = temp;
}

The following example code shows an example of calling a method with int as the type parameter:

int a = 1;
int b = 2;
...
Swap<int> (A, b);

You can also omit the type parameter and the compiler will infer it. The code to call swap below is equivalent to the example above:

Swap (A, b);

Static methods and instance methods have the same type inference rules. The compiler is able to infer the type parameters based on the passed method parameters, rather than judging by the constraints or return values alone. Therefore, type inference is not valid for methods that do not have parameters. Type inference occurs at compile time, and before the compiler resolves the overloaded method flags. The compiler applies type inference logic to all generic methods with the same name. In the decision (resolution) overload stage, the compiler contains only those generic classes whose type inference is successful.

In a generic class, a non-generic method can access a type parameter in the same class:

Class list<t>
{
void Swap (ref T LHS, ref t RHS) {...}
}

In a generic class, you define a generic method that has the same type parameters as the class in which it resides, and when you try to do this, the compiler generates a warning CS0693.

Class list<t>
{
void swap<t> (ref T LHS, ref t RHS) {}
}

Warning CS0693: The type parameter "T" has the same name as the type parameter in the external type "list<t>"

In a generic class, you define a generic method that defines a type parameter that is not defined in a generic class: (infrequently used, general mate constraints use)

Class list<t>
{
void swap<u> (ref T LHS, ref t RHS) {}//infrequently used

void add<u> (list<u> items) where u:t{}//Common
}

Generic methods are overloaded by multiple type parameters. For example, the following methods can be placed in the same class:

void DoSomething () {}
void Dosomething<t> () {}
void Dosomething<t, U> () {}

Viii. Default keyword in generics

One of the problems in generic and generic methods is how to assign a default value to a parameterized type, at which point the following two points cannot be known in advance:

    1. Whether t will be a value type or a reference type

    2. If T is a value type, then T will be numeric or structure

For a variable t with a parameterized type T, the t = NULL statement is legal only if T is a reference type, and t = 0 is valid only for numeric values, but not for structs. The solution to this problem is to use the default keyword, which returns null for the reference type, and zero for the numeric value type. For structs, it returns each member of the struct, and returns 0 or null depending on whether the member is a value type or a reference type.

Class genericclass<t>
{
T getelement ()
{
return default (T);
}
}
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.