C # Common Interface Learning ienumerable<t>

Source: Internet
Author: User

C # Common Interface Learning ienumerable<t>Wu Long Harry
Date: 2015-10-24
Platform: Window7 64bit,visual Studio Community This article refers to:
    • MSDN ienumerable<t> Interface
    • MS DotNet Source Code
    • Have you ever achieved a two-prong tree--10 years of ingenuity?
    • You may not know the trap, IEnumerable interface--Desert Eagle
This chapter:
Text:

This article is for the author to grope for learning. NET process, progressive, more cumbersome, is the author himself to help remember the blog post.

Let's take a look at the public first. How the four interfaces of Ienumerable<t>, IEnumerable, ienumerator<t>, and IEnumerator in the source program of Net4.0 are declared:

     Public Interfaceienumerable< outT>: IEnumerable {NewIenumerator<t>GetEnumerator (); }      Public Interfaceienumerator< outT>: IDisposable, IEnumerator {NewT Current {Get; }    }     Public InterfaceIEnumerable {IEnumerator GetEnumerator (); }     Public InterfaceIEnumerator {BOOLMoveNext (); Object Current {Get; }            voidReset (); }
View Code


First, the interface IEnumerable implementation

1. Build a student data structure and a student collection class:

    Student data structure    class Student    {public        int id;        public string name;    Student collection    class studentcollection    {public        list<student> students = new list<student> () ;        public void Add (Student Student)        {            students. ADD (student);        }    }

Exposing an Add () method to add data, our collection class is established. Down to add data:

        static void Main (string[] args)        {            Studentcollection sc = new studentcollection ();            Sc. ADD (new Student {id=0,name= "Tony"});            Sc. ADD (new Student {id=1,name= "micheal"});            Sc. ADD (new Student {id =2, name = "Amy"});            foreach (var s in SC) {...}}}    

When we want to traverse with foreach (), the compiler tells us that studentcollection does not contain GetEnumerator and cannot be traversed with a foreach. Although the studentcollection has a list<t> that can be traversed, we do not want to iterate over the attributes, and we want to iterate over the class, not

foreach (var s in sc.students) {...}

Now it is only to transform our Studentcollection class into a foreach one.

2, Inherit the interface IEnumerable:

When we add: IEnumerable after the class, the Visual Studio ide pops up with a small yellow light bulb that points to a convention that automatically fills in the interface, and we choose the first implementation interface (Visaul Studio is the most intimate ide! in the world), The IDE will help us transform the sudentcollection into the following:

    Class studentcollection:ienumerable    {public        list<student> students = new list<student> ();        public void Add (Student Student)        {            students. ADD (student);        }        Public IEnumerator GetEnumerator ()        {            throw new notimplementedexception ();        }    }

Adds a method getenumrator that returns an iterator. Down according to the Ienumetator interface Convention to implement our iterator Studentcollectionenumerator, the IDE automatically complete the code as follows:

    Iterator    class Studentcollectionenumerator:ienumerator {public        object current        {            get            {                throw new NotImplementedException ();            }        }        public bool MoveNext ()        {            throw new notimplementedexception ();        }        public void Reset ()        {            throw new notimplementedexception ();        }    }

My understanding is this: current returns the element, MoveNext moves to the next one, and reset goes back to the first element. But according to MSDN above, the Reset method provides COM interoperability. It does not necessarily need to be implemented; instead, implementers simply throw NotSupportedException. However, if you choose to do this, you should make sure that no callers rely on the reset feature.

The iterator works by first calling the MoveNext () method and then reading the current to get the element until MoveNext returns false.

We need 3 fields to place the element's position, element, and element set, respectively. The following procedures are changed:

 //iterator class Studentcollectionenumerator:ienumerator {private int _        Index        Private list<student> _collection;        private Student value;            Public Studentcollectionenumerator (list<student> colletion) {_collection = colletion;        _index =-1;        } object IEnumerator.Current {get {return value;}            } public bool MoveNext () {_index++; if (_index >= _collection.            Count) {return false;}            else {value = _collection[_index];}        return true;        } public void Reset () {_index =-1; }    }

First, the iterator initializes, introduces the element set _collection, and sets the index _index to-1. Set to 1 instead of 0 because the iterator first calls MoveNext, and in MoveNext we first point index +1 to the next element, and if the value of the index _index is initially 0, then the first element is the element set [1] and the second element.
Second, we want to change the object current to IEnumerator.Current, which is the key to implementing the iterator. Returns the element. (as if there was a boxing act)
Thirdly, the index is accumulated within the MoveNext method and the elements are read from the element set. Then let the index value go beyond the element set to return a value of false.
Finally, the index value is 1 in the Reset method, but it seems to be a direct throw error.

The iterator is written, and we call it in the Studentcolletion class:

   Class studentcollection:ienumerable    {public        List students;        Public studentcollection ()        {            students = new List ();        }        public void Add (Student Student)        {            students. ADD (student);        }        Public IEnumerator GetEnumerator ()        {            return new Studentcollectionenumerator (students);        }    

Test run, Done! We have implemented our own classes that can be enumerated.

Through observation, it is found that the main iterator is to return an element object, and studentcolletion inside the students element set is a list, itself can be enumerated, we can not use this special write iterator to implement the enumeration?
The answer is yes, we write:

    Class studentcollection:ienumerable    {public        list<student> students = new list<student> ();        public void Add (Student Student)        {            students. ADD (student);        }        Public IEnumerator GetEnumerator ()        {            foreach (var s in students)            {                yield return s;            }        }    }

This will enable enumeration, really simple, full use. NET gives a variety of enumerable collections, no longer to write GetEnumerator this dirty.

Second, the interface ienumerable<t> realization

If we want to write a generic, foreach class, use generics:

    Class mycollection<t>    {public        list<t> mycollection = new list<t> ();        public void  ADD (T value)        {            mycollection. ADD (value);        }    }

In fact, this mycollection class is just outside the list<t> package a layer, to achieve ienumable<t>, inherit the generic interface, Visual Studio IDE automatically help us complete the following:

    Class mycollection:ienumerable    {public        list mycollection = new list ();        public void  ADD (T value)        {            mycollection. ADD (value);        }        Public IEnumerator GetEnumerator ()        {            throw new notimplementedexception ();        }        IEnumerator Ienumerable.getenumerator ()        {            throw new notimplementedexception ();        }    }

We directly use the second simple notation above, to change to:

    Class mycollection:ienumerable    {public        list mycollection = new list ();        public void  ADD (T value)        {            mycollection. ADD (value);        }        Public IEnumerator GetEnumerator ()        {            foreach (var s in mycollection)            {                yield return s;            }        }        IEnumerator ienumerable.getenumerator ()        {            foreach (var s in mycollection)            {                yield return s;}}    }

Test run:

static void Main (string[] args)        {            mycollection mc = new mycollection ();            Mc. ADD (0);            Mc. ADD (1);            Mc. ADD (2);            foreach (Var s in MC) {Console.WriteLine (s);}            Console.readkey ();        }

Done!

Although the second is more speculative, it takes advantage of the various generic collections that the. NET framework gives to enumerate the characteristics. But we also implemented a GetEnumerator () to understand how the enumerator works. This chapter aims to achieve learning.

C # Common Interface Learning ienumerable<t>

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.