C # Generic Programming

Source: Internet
Author: User

1. The concept of generics

Generics in C # are similar to templates in C + +, which are established by types or classes that are provided during instantiation. Generics are not limited to classes, but you can also create generic interfaces, generic methods, and even generic delegates. This greatly increases the flexibility of the code and the correct use of generics can significantly shorten development time. Unlike C + +, all operations in C # are performed during run time.

2. Using generics

    • Nullable Types

Value types must contain a value that can exist after the declaration, before assignment, in an unassigned state, but cannot be used in any way, and the reference type can be null. Sometimes it is useful to have a value type of NULL, and generics provide a way to use system.nullable<t> to make a value type empty. The following code:

Private nullable<int> _nullableint;

You can assign null to _nullableint, as follows:

_nullableint = null;

Nullable types are so useful that syntax is added to C #:

Int? _nullableintsecond;

    • System.Collections.Generic name Space

This namespace is used to handle the generic type of the collection and is used very frequently. Examples of these classes are presented in list<t> and Dictionary<k,v>, along with the interfaces and methods used with them.

1.list<t>

list<t> Generic collection classes are faster and easier to use, creating collections of T-type objects requires a method:

list<string> _mycollection = new list<string> ();

A list collection with T As String will be created.

You can see the methods supported by list<t> in your code, and we won't repeat them here.

2. Sorting and searching for generic lists

Sorting and searching the generic list is the same as sorting and searching the other lists, as shown in the example code:

 Public classnumbercollection:list<int>    {         PublicNumbercollection (ienumerable<int>initialnums) {            foreach(varNuminchinitialnums)            {ADD (num); }        }         Publicnumbercollection () { for(intI=0; I <Ten;++i) {Add (i); }        }         Public voidPrint () {foreach(varNuminch  This) {Console.WriteLine (num);        } console.read (); }    }
 Public Static classNumbercollectiondelegate { Public Static intCompare (intIintj) {if(I >j) {return-1; }            Else if(I <j) {return 1; }            return 0; }         Public Static BOOLFind (inti) {ifI2==0)            {                return true; }            return false; }

public static comparison<int> copmaredelegate = new comparison<int> (Compare);

public static predicate<int> predicate = new predicate<int> (Find);

    }
var New numbercollection (); Numcolleciton.print (); Numcolleciton.sort (numbercollectiondelegate.copmaredelegate); Numcolleciton.print (); var New numbercollection (Numcolleciton.findall (numbercollectiondelegate.predicate)); Newnumcollection.print (); Console.ReadLine ();

As the above code, first defines the numbercollection inherited from the List<int>, defines the print method to output all the values in the collection, class Numbercollectiondelegate defines the Compare method, As well as the Find method, the Compare method is used to sort the collection in descending order (why this is a descending sort note for another article), and the Find method is used to select even values in the collection. In the use of an instance, the elements in the collection are first sorted in descending order, and then the values of the even number in the collection are selected to form a new collection, although the above comparison and lookup usage can be simplified to the following usage:

Numcolleciton.sort (Numbercollectiondelegate.compare);

var newnumcollection = new Numbercollection (Numcolleciton.findall (Numbercollectiondelegate.find));

This does not require the display of the reference comparison<int> type, but the comparison<int> instance is still created implicitly when used, as is the case for comparisons. In many cases, you can use method groups to implicitly create delegates in such a way that the code becomes easier to read.

3.dictionary<k,v>

This type defines a collection of key-value pairs that instantiate two types, one for the keys and one for the values, to represent the individual items in the collection. You can use the strongly typed Add method to add a key-value pair, as follows.

dictionary<string, int> stringintdictionary = new dictionary<string, int> ();
Stringintdictionary.add ("Tom", 1);
Stringintdictionary.add ("Lucy", 2);
Stringintdictionary.add ("Lily", 3);

You can directly access keys and values in the Dicitionary:

foreach (var key in Stringintdictionary.keys)
{
Console.WriteLine (key);
}

foreach (var value in stringintdictionary.values)
{
Console.WriteLine (value);
}

You can also iterate over each item in the collection, as follows:

foreach (keyvaluepair<string,int> item in stringintdictionary)
{
Console.WriteLine ("{0} = {1}", item.) Key, item. Value);
}

One thing to note about Dictionary<k,v> is that the keys for each item must be unique. If you add an item that has the same key value as an existing item, an exception is thrown.

3. Defining generics

1. Defining generic Classes

to create a generic class, you simply include the angle brackets in the class definition:

Class mygenericclass<t>
{
}

where t can be any identifier, just follow the C # naming convention, but generally only use T.

A generic class can contain any number of types in its definition, separated by commas, for example:

Class mygenericclass<t1,t2,t3>
{
}

After defining these types, you can use them in the class definition as you would with other types, as follows

class Mygenericclass<t1,t2,t3>    {        private  T1 _object;          Public MyGenericClass (T1 Item)        {              _object = Item;        }          Public T1 Innert1object        {            get            {                return  _object;}}    }

Note You cannot assume what type is used, for example:

_object = new T1 ();

Because you do not know what T1 is now, you cannot use its constructor, perhaps T1 has no constructors, or there are no publicly accessible constructors. Therefore, the actual operation of generics requires more information about the type of use.

    • Default keyword

To determine the instance used to create a generic type, you need to know the most basic case, whether it is a reference type or a value type, and you cannot directly assign a null value to a variable without knowing the situation. At this point the default keyword comes in handy:

_object = Default (T1);

If _object is a reference type, the reference type is assigned a null value, and if it is a value type, it is assigned the default value. For numeric types, the default value is 0, and for structs, they are assigned according to the same rules. The default keyword allows for more operations on the types that must be used, and more constraints must be made on the types used in order to do more.

    • Constraint type

The types used earlier are called unbound types, because they are not constrained by any constraints, and the types used for generics can be qualified by constraints. In a class definition, you can use the WHERE keyword to qualify a type for a generic type, as follows:

Class mygenericclass<t1,t2,t3> where T1:constraint

Where constraint defines constraints, you can define many constraints in this energy mode, separating each constraint with a comma. You can also use multiple where statements to define constraints on any type or all types required by a generic type, and the constraint must appear after the type descriptor.

    • Inherit from a generic class

classes can inherit from generics, such as

Class farm<t>: ienumerable<t> where T:animal
{
}

As the above code farm<t> is an interface type, a constraint on T also adds an additional constraint on the t used in IEnumerable, which can be used to restrict the type used for the constraint, but some rules need to be followed.

First, if a type inherits from a base type that is constrained, the type cannot touch the constraint, that is, when the type T is used in the base class, it must be extended to the subclass, at least the same as the constraints of the primary class.

    • Generic operators

Generic classes also support overrides of operators.

    • Generic structure

structs are the same as classes, but there are some subtle differences, and structs are value types, not reference types, so you can create generic structures such as:

struct MYGENERICSTRUCT<T1, t2>
{
}

2. Defining a generic interface

Defining generic interfaces is the same technique used to define generic classes, for example:

  Interface where T:object    {        void  Sum (t x, t y);    }

3. Defining generic methods

You can use a generic method to achieve a more general form of a generic method in which the parameter type or return type is determined by the generic type parameter.

For example:

  T getdefault<t>()           {               returndefault(t);           }

You can use non-generic classes to implement generic methods:

    Public class defaulter    {        public T getdefault<t>()        {             returndefault  (T);        }    }

If the class is generic, you need to provide a different identifier for the generic method in the class. The following code will prompt for a generic method:

   Public class Defaulter<t>    {        public T getdefault<t>()        {             return  default(T);        }    }

You are prompted to change the generic identifier when the internal generic parameter is the same as the external generic parameter.

This article refers to the C # Getting started classic.

C # Generic Programming

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.