C # -- generic (3)

Source: Internet
Author: User

Introduction: The first two articles talk about the basics of generics. I will introduce them to my friends who are new to generics through this article. <1>. things of principle ---- "generic covariant and inverter" <2>. and common interfaces ---- "IEnumerable and its generic version of IEnumerable <out T>" ----------------------------- <generic covariant and inverter | generic modifier 'out' and 'in'> | first, you do not need to care about the terms of the two inspector, the crowdsourced security testing platform is mainly used for generic interfaces and delegation. We can use an example to look at this process: | before that, we need to insert something else, we know that interfaces can reflect polymorphism. Of course, the polymorphism embodied in the interface focuses on the Functional polymorphism, which is different from the abstract class, the abstract class pays more attention to the polymorphism established on the kinship. After knowing that the interface can reflect polymorphism, let's take a look at a related example-birds and planes can fly and define flying as an excuse, copy the code public interface IFlyable {void fly ();} class Bird: IFlyable {public void fly () {Console. writeLine ("Birds fly! ") ;}} Class Plane: IFlyable {public void fly () {Console. WriteLine ("! ") ;}} Copy the code to see the polymorphism embodied in the interface: copy the code IFlyable ifly; ifly = new Bird (); ifly. fly (); ifly = new Plane (); ifly. fly (); copy the code running result: bird fly! Plane flying! After learning about the interface polymorphism, let's look at an example: here we define two classes Animal and Cat (Cat inherits Animal). Copy the code public class Animal {} public class Cat: animal {} copy the code to continue reading: Cat cat = new Cat (); the following code, cat to animal, subclass to parent class conversion, at this time, cat is implicitly converted to animal. We say "Son is like Father". This is completely understandable. Animal animal = cat; but said "father is like a son, however, sometimes, if my son is a zombie, the cat = (Cat) animal can be forcibly converted; (covariant) List <Cat> catArray = new List <Cat> (); list <Animal> animalArray = catArray; if it is the class mentioned above, this can be written, but this But IEnumerable <Cat> lCat = new List <Cat> (); IEnumerable <Animal> lAnimal = lCat; to define IEnumerable <Cat>, we found that the concept of "out" is introduced here: 1. for generic type parameters, the out keyword specifies that this type parameter is covariant. You can use the out keyword in generic interfaces and delegation. "Covariant" refers to a type with a greater degree of derivation than the original specified derivative type. -- The author understands "covariant" in this way, that is, "the general change" is like "The son is like the father" (assuming that the father has a degree of 0, the degree of son derivation is 1, therefore, the father can use a son with a higher degree of derivation.) The Association is similar to polymorphism, so it looks very natural. (Invert) We know that in the IComparable <T> interface, the modifier T is 'in'. Let's modify the above Code to demonstrate copying the code class Cat: Animal, IComparable <Cat >{// only demonstrate public int CompareTo (Cat other) {return 1 ;}} class Animal: IComparable <Animal >{// only demonstrate public int CompareTo (Animal other) {return 1 ;}} copy the code here Cat and Animal both implement the IComparable <T> interface, then we write the IComparable <Cat> ICat = new Cat (); IComparable <Animal> IAnimal = new Animal (); ICat = IAnimal; ICat (high-derivative) Degrees) The use of IAnimal (low degree of derivation) "father like son" is totally different from the above example. Concept Introduction: 2. For generic parameters, the in keyword specifies that this type parameter is inverter. You can use the in keyword in generic interfaces and delegation. "Invert" refers to a type that can be derived to a smaller extent. -- The author's understanding of "inverter" is that "father-like son", in turn, is hard to say "father-like son". This is "not to be said". However, after learning about the above content, let's take a look at the features of the "out" and "in" keywords. The IEnumerator <T> GetEnumerator () method of the IEnumerable <T> interface returns an iterator, it is not difficult to find that if T is marked with an out, T represents the output, that is, it can only be returned as a result. The CompareTo (T other) method of the IComparable <T> interface passes in a T-type Other parameter. It is not difficult to find that if T is marked with in, T represents the input, that is, it can only be passed in as a parameter. The following example shows how to define an animal as this function as a generic excuse to use out to modify it. here an error occurs to put the second setSound method with parameters, after the compilation is removed, we can use the following code to change out to in. Here, an error will occur to change the first setSound method. After the code is removed, it can pass the compilation normally or return the value of the first method, if it is changed to another non-T type, the compilation can also fully demonstrate that T can only be used as the result output but not as a parameter when T is modified by out; if in modifies T, T can only be used as a parameter but cannot be returned as a result; then --------------------------- <IEnumerable Interface And its generic version> Why use the IEnumerable interface? The following example shows how to copy the code // define the Person class public class Person {public Person (string _ name) {this. name = _ name;} public string name;} // defines the People class public class People {private Person [] _ people; public People (Person [] pArray) {// The instantiated array is used to store the Person instance _ people = new Person [pArray. length]; for (int I = 0; I <pArray. length; I ++) {_ people [I] = pArray [I] ;}} copy the code above. We define a Person class and a People class, obviously, People is used to store multiple Next we try to use Foreeach to traverse the output of each element in the Set: copy the code static void Main (string [] args) {Person [] personArray = new Person [3] {new Person ("Keiling1"), new Person ("Keiling2"), new Person ("Keiling3 "),}; people people = new People (personArray); foreach (Person item in people) {Console. writeLine (item. name) ;}} the Code cannot be compiled here. An error occurs: GetEnumerator: A method in the IEnumerable interface. It returns an IEnumerator (iterator), as specified by IEnumerator. All the basic methods for implementing an iterator, including for example, to use the People instance in foreach, we implement the IEnumerable interface for People. The Code is as follows: copy the code public class People: IEnumerable {private Person [] _ people; public People (Person [] pArray) {// The instantiated array is used to store the Person instance _ people = new Person [pArray. length]; for (int I = 0; I <pArray. length; I ++) {_ people [I] = pArray [I] ;}/// IEnumerable and IEnumerator establish a connection through the GetEnumerator () method of IEnumerable, you can use GetEnumerator () of IEnumerable to obtain IEnumerator object. IEnumerator IEnumerable. getEnumerator () {return (IEnumerator) GetEnumerator ();} public PeopleEnum GetEnumerator () {return new PeopleEnum (_ people);} public class PeopleEnum: IEnumerator {public Person [] _ people; public PeopleEnum (Person [] pArray) {_ people = pArray;} // cursor int position =-1; // whether the public bool MoveNext () {position ++; return (position <_ people. length);} // all elements in the set are duplicated Set position public void Reset () {position =-1 ;}// implement the Current method of IEnumerator to return the Current Person object IEnumerator. current {get {return Current; }}// Current is the read-only method of the Person class instance. public Person Current {get {try {return _ people [position];} catch (IndexOutOfRangeException) {throw new InvalidOperationException () ;}}} copy the code to test run: copy the code static void Main (string [] args) {Person [] personArray = new Pers On [3] {new Person ("Keiling1"), new Person ("Keiling2"), new Person ("Keiling3"),}; People people = new People (personArray ); foreach (Person item in people) {Console. writeLine (item. name) ;}} copy the code result: Conclusion: 1. to support foreach traversal, a set must implement the IEnumerable interface, which describes the objects that implement this interface. We call it 'sequence '. For example, List <T> supports foreach traversal because it implements the IEnumerable interface and its generic version, -- 2. the IEnumerator object implements the iterator (through MoveNext (), Reset (), Current ). 3. we can also see the difference between the two interfaces in terms of terms: IEnumerable is a declarative interface, and the class that declares the implementation of this interface is "enumerable, however, it does not explain how to implement the iterator, while IEnumerator is an implementation interface, and the IEnumerator object is an iterator. For more information about IEnumerable, see the following code: 4. because IEnumerable <T> inherits the IEnumerable interface, to implement IEnumerator <T>, you also need to implement the IEnumerator interface. Because it is the same as the method in the generic version, therefore, the implementation of this method must be implemented using an explicit interface. Here we will not continue to introduce its specific implementation, which is basically the same as IEnumerator. Here we will not detail it. You can write it yourself. Ps understanding of IEnumerable and IEnumerable <T> will be of great help to learn more about LINQ in the future.

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.