[C #] generic

Source: Internet
Author: User
Generic is a new function in the C # language and Common Language Runtime Library (CLR) of version 2.0. Generics introduce the concept of type parameters. net Framework, type parameters make it possible to design the following classes and Methods: these classes and Methods delay one or more types until the client Code declares and instantiate the class or method. For example, by using the generic type parameter T, you can write a single class that can be used by other client code without introducing the cost or risk of force conversion or packing during runtime, as shown below:

// Declare the generic class

Public class genericlist <t>

{

Void add (T input ){}

}

Class testgenericlist

{

Private class exampleclass {}

Static void main ()

{

// Declare a list of Type int

Genericlist <int> list1 = new genericlist <int> ();

// Declare a list of Type string

Genericlist <string> list2 = new genericlist <string> ();

// Declare a list of Type exampleclass

Genericlist <exampleclass> list3 = new genericlist <exampleclass> ();

}

}

You can use generic types to maximize code reuse, protect type security, and improve performance.

The most common use of generics is to create a collection class.

The. NET Framework class library contains several new generic collection classes in the system. Collections. Generic namespace. Use these classes as much as possible to replace common classes, such as the arraylist in the system. Collections namespace.

You can create your own generic interfaces, generic classes, generic methods, generic events, and generic delegation.

You can restrict generic classes to access specific data types.

Information about types used in generic data types can be obtained through reflection at runtime.

Bytes ------------------------------------------------------------------------------------------

 

Generic is the most powerful function of C #2.0. You can define a type-safe data structure through the generic type without using the actual data type. This significantly improves performance and produces higher quality code because you can reuse data processing algorithms without replicating specific types of code. In terms of concept, generics are similar to C ++ templates, but there are significant differences in implementation and functions. This article discusses the problem space of generic processing, their implementation methods, the benefits of this programming model, and unique innovations (such as constraints, general methods and delegation, and general inheritance ). You will also learn about. other fields of the. NET Framework, such as reflection, array, set, serialization, and remote processing, use generics and improve the basic functions provided.

Bytes ------------------------------------------------------------------------------------------

C # Generic demonstration

Class Stack <t>
{
Private T [] store;
Private int size
Public stack ()
{
Store = new T [10];
Size = 0;
}

Public void push (t x)
{
Store [size ++] = X;
}

Public void t POP ()
{
Return store [-- size];
}
}

Stack <int> X = new stack <int> ();
X. Push (17 );

Generic Introduction

Generic: You can use parameterized data types to operate multiple data types on the same code. Generic programming is a programming paradigm that abstracts types by using parametric types to achieve more flexible reuse.

C # generics give the code stronger type security, better reuse, higher efficiency, and clearer constraints.

C # Introduction to generic mechanisms

C # generic capabilities are supported by CLR at runtime. They are different from C ++'s compile-time template mechanism and Java's compile-time "erase ". This enables seamless interoperability between languages that support CLR.

C # When the generic code is compiled as Il and metadata, special Placeholders are used to represent the generic type and proprietary il commands are used to support generic operations. The real generic instantiation work is in the "On-Demand" mode, which occurs during JIT compilation.

C # Generic compilation Mechanism

During the first round of compilation, the compiler only generates "generic version" il code and metadata for the stack <t> type, and does not instantiate the generic type. t serves as a placeholder in the middle.

During JIT compilation, when the JIT compiler encounters a stack <int> for the first time, it replaces the "generic version" il code with the T -- in the metadata to instantiate the generic type.

CLR generates the same code for all generic types whose type parameters are "reference type". However, if the type parameter is "Value Type", for each different "Value Type ", CLR generates an independent code for it.

C # characteristics of generics

If the parameters of the instantiated generic type are the same, the JIT compiler will reuse this type, therefore, the dynamic generic capability of C # avoids code expansion problems caused by C ++ static templates.

C # generic types carry rich metadata, So C # generic types can be applied to powerful reflection technologies.

The generic type of C # adopts the constraints of "base class, interface, constructor, value type/reference type" to implement "display constraint" on type parameters ", this improves the type security, and also loses the high flexibility of the C ++ template based on the "signature" implicit constraint.

C # generic classes and structures

Class C <u, v >{} // valid
Class D: C <string, int >{} // valid
Class E <u, v>: C <u, v >{} // valid
Class F <u, v>: C <string, int >{} // valid
Class G: C <u, v >{} // invalid

C # besides declaring generic types (including classes and structures), you can also include the declaration of generic types in the base class. However, if a base class is a generic class, its type parameters are either instantiated or declared by the source subclass (also generic.

Generic Type members

Class C <v>
{
Public v F1; // declare a field
Public d <v> F2; // as a parameter of other generic types
Public C <v x>
{
This. F1 = X;
}
}

Generic Type members can use the type parameters in the generic type declaration. However, if the type parameter does not have any constraints, you can only use a common member inherited from system. Object on this type.

Generic Interface

Interface ilist <t>
{
T [] getelements ();
}
Interface idictionary <K, V>
{
Void add (K key, V value );
}
// The type parameter of the generic interface is either instantiated
// Either comes from the type parameter of the implementation class declaration

Class list <t>: ilist <t>, idictionary <int, T>
{
Public T [] getelements {}
{
Return NULL;
}
Public void add (INT index, T value ){}
}

Generic Delegation

Delegate bool predicate <t> (T value );
Class X
{
Static bool F (int I ){...}
Static bool g (string s ){...}
Static void main ()
{
Predicate <string> P2 = g;
Predicate <int> P1 = new predicate <int> (f );
}
}
Generic delegation supports parameter types for returned values and parameter inner sensing. These parameter types can also be subject to legal constraints.

Introduction to generic methods

C # The generic mechanism only supports "containing type parameters in method declaration"-that is, generic methods.

C # The generic mechanism does not support the inclusion of type parameters in declarations of other members except the method (including attributes, events, indexers, constructors, and Destructors, however, these members can be contained in generic types and use generic type parameters.

Generic methods can be included in both generic and non-generic types.

Declaration and call of generic methods

Public class Finder
{
// Declaration of generic methods
Public static int find <t> (T [] items, t item)
{
For (INT I = 0; I <items. length; I ++)
{
If (items [I]. Equals (item)
{
Return I;
}
}
Return-1;
}
}

// Call a generic Method
Int I = finder. Find <t> (New int [] {1, 3, 4, 5, 6, 8, 9}, 6 );

Generic programming

Overload of generic methods

Class myclass
{
Void F1 <t> (T [] A, int I); // The overload method cannot be constructed.
Void F1 <u> (U [] A, int I );

Void F2 <t> (int x); // overload method
Void F2 (int x );

Void F3 <t> (t) where T: A; // The overload method cannot be constructed.
Void F3 <t> (t) where T: B;
}

Override of generic methods

Abstract class base
{
Public abstract t f <t, u> (t, u) where u: T;
Public abstract T g <t> (t) where u: icomparable;
}
Class derived: Base
{
// Valid rewrite. The constraint is inherited by default.
Public override x F (x, y) (x, y ){}

// Invalid rewrite. It is unnecessary to specify any constraints.
Public override T g <t> (t) where T: comparable {}
}

Introduction to generic Constraints

C # any assumption of "all generic type or generic method type parameters" must be based on "Explicit Constraints ", to maintain the type security required by C.

"Explicit constraint" is expressed in the WHERE clause. You can specify "base constraint", "interface constraint", and "constructor constraint ", there are four constraints in "value type/reference type constraint.

"Display constraint" is not mandatory. If "Explicit constraint" is not specified, generic parameters can only access public methods in the system. Object type.

Base Constraint

Class
{
Public void F1 (){}
}
Class B
{
Public void F2 (){}
}

Class C (S, T)
Where s: A // s inherited from
Where T: B // t inherited from B
{
// You can call F1 on a variable of type S.
// You can call F2 on a variable of the T type.
}

Interface Constraints

Interface iprintable {coId print ();}
Interface icomparable <t> {int compareto (t v );}
Interface ikeyprovider <t> {T hetkey ();}

Class dictionary <K, V>
Where K: icomparable <k>
Where V: iprintable, ikeyprovider <k>
{
// You can call compareto on a variable of K type
// Print and getkey can be called on a variable of the V type.
}

Constructor Constraints

Class
{
Public (){}
}
Class B
{
Public B (int I )()
}

Class C <t>
Where T: New ()
{
// T = new T () can be used in it ();
}
C <A> C = new C <A> (); // yes. A has no parameter constructor.
C <B> C = new C <B> (); // error. B does not have a parameter constructor.

Value Type/reference type constraints

Public struct {...}
Public Class B {...}

Class C <t>
Where T: struct
{
// T is a value type.
}
C <A> C = new C <A> (); // yes. A is a value type.
C <B> C = new C <B> (); // error. B is a reference type.

Summary

C #'s generic capabilities are supported by CLR at runtime. They are different from the static templates supported by C ++ during compilation, it is also different from the simple type supported by Java's use of the "erase method" at the compiler level.

C # supports four generic types, including class, structure, interface, and delegate, and method members.

The generic type of C # adopts the constraints of "base class, interface, constructor, value type/reference type" to implement "Explicit Constraints" on type parameters ", it does not support explicit signature-based constraints like the C ++ template.

 

 

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.