Ienumerable, ienumerator

Source: Internet
Author: User

Ienumerator: Provides interfaces that can be traversed in common sets, including current, movenext (), and reset (). In this example, current returns the object type.
Ienumerable: exposes an ienumerator that supports traversal in a common set.
Ienumerator <t>: inherits from ienumerator. It has the current attribute and returns the T type.
Ienumerable <t>: inherits from ienumerable, exposes an ienumerator <t>, and supports traversing in generic sets.

1. To make the custom set type support foreach access, you must implement the ienumerable interface.

2. In many cases, we have discussed why the newly added generic interface ienumerable <t> should inherit ienumerable to ensure compatibility. Theoretically, all generic interfaces must inherit from all non-generic interfaces. For example. NET 1.1 has a method that receives ienumerable parameters. When transplanted to a new environment, we pass in an ienumerable <t> parameter, which is also acceptable, they all perform enumeration.

However, ilist <t> does not inherit from the ilist interface, because if you want ilist <t> to inherit ilist, to implement the ilist <int> class, you need to implement two insert methods. One is the void insert (INT index, int item) of the ilist <int> ), the other is the void insert (INT index, object item) of ilist. This is an interface that can insert object-type data into the ilist <int> set. This is incorrect, so do not inherit.

The difference between ienumerable <t> is that it only acts as an "output", that is, we only retrieve data from it, so there is no confusion described above.

3. The example below describes how to use
First, there is a person class:

Public class person
{
Public Person (string fname, string lname)
{
This. firstname = fname;
This. lastname = lname;
}

Public String firstname;
Public String lastname;
}


The first method is to implement the people set:

Public class people: ienumerable
{
Private person [] _ people;
Public people (person [] parray)
{
_ People = new person [parray. Length];

For (INT I = 0; I <parray. length; I ++)
{
_ People [I] = parray [I];
}
}

Public ienumerator getenumerator ()
{
Return new peopleenum (_ people );
}
}

Public class peopleenum: ienumerator
{
Public person [] _ people;

// Enumerators are positioned before the first element
// Until the first movenext () call.
Int position =-1;

Public peopleenum (person [] list)
{
_ People = List;
}

Public bool movenext ()
{
Position ++;
Return (position <_ people. Length );
}

Public void reset ()
{
Position =-1;
}

Public object current
{
Get
{
Try
{
Return _ people [position];
}
Catch (indexoutofrangeexception)
{
Throw new invalidoperationexception ();
}
}
}
}


Second, let people implement the ienumerator interface:

Public class people: ienumerable, ienumerator
{
Private person [] _ people;
Int position =-1;

Public people (person [] parray)
{
_ People = new person [parray. Length];

For (INT I = 0; I <parray. length; I ++)
{
_ People [I] = parray [I];
}
}

# Region ienumerable members

Public ienumerator getenumerator ()
{
Return this;
}

# Endregion

# Region ienumerator members

Public object current
{
Get
{
Try
{
Return _ people [position];
}
Catch (indexoutofrangeexception)
{
Throw new indexoutofrangeexception ();
}
}
}

Public bool movenext ()
{
Position ++;
Return (position <_ people. Length );
}

Public void reset ()
{
Position =-1;
}

# Endregion
}


The third method specifies the type with the generic type:

Public class people: ienumerable <person>, ienumerator <person>
{
Private person [] _ people;
Int position =-1;

Public people (person [] parray)
{
_ People = new person [parray. Length];

For (INT I = 0; I <parray. length; I ++)
{
_ People [I] = parray [I];
}
}

# Region ienumerable <person> Members

Public ienumerator <person> getenumerator ()
{
Return this;
}

# Endregion

# Region ienumerable members

Ienumerator ienumerable. getenumerator ()
{
Return this;
}

# Endregion

# Region ienumerator <person> Members

Public Person current
{
Get
{
Try
{
Return _ people [position];
}
Catch (indexoutofrangeexception)
{
Throw new indexoutofrangeexception ();
}
}
}

# Endregion

# Region idisposable members

Public void dispose ()
{
}

# Endregion

# Region ienumerator members

Object ienumerator. Current
{
Get
{
Try
{
Return _ people [position];
}
Catch (indexoutofrangeexception)
{
Throw new indexoutofrangeexception ();
}
}
}

Public bool movenext ()
{
Position ++;
Return (position <_ people. Length );
}

Public void reset ()
{
Position =-1;
}

# Endregion
}


Then you can use foreach to access the custom set:
Person [] fig = new person [3]
{
New person ("John", "Smith "),
New person ("Jim", "Johnson "),
New person ("Sue", "rabon "),
};

People peoplelist = new people (inclulearray );
Foreach (person P in peoplelist)
Console. writeline (P. firstname + "" + P. lastname );

The following describes how to use the yield Keyword:

Note: first, it can only be used in one iterator method. That is to say, the return value type of this method can only be ienumerable, ienumerator, ienumerable <t> or ienumerator <t>. Second, it has only two syntaxes: yield return expression; or yield break;
For example, the following method uses yield return to return each value that meets the condition in the loop, but does not exit:
Public static class numberlist
{
// Create an array of integers.
Public static int [] ints = {1, 2, 3, 5, 8, 13, 21, 34,55, 89,144,233,377 };
// Define a property that returns only the even numbers.
Public static ienumerable <int> geteven ()
{
// Use yield to return the even numbers in the list.

Foreach (int I in ints)

If (I % 2 = 0)
Yield return I;
}
}

The call is as follows:
// Display the even numbers.
Console. writeline ("even numbers ");
Foreach (int I in numberlist. geteven ())
Console. writeline (I );

In this iterator loop, only yield break can be used to exit the loop (and the entire method is also exited). If break is used, it cannot be compiled. For example:
Public static ienumerable <int> geteven ()
{// Use yield to return the even numbers in the list.

Foreach (int I in ints)
If (I % 2 = 0)
Yield break;

Console. writeline ();
}
If yield break; is executed, the following console. writeline (); will not be executed. The entire method body will exit after yield break is executed.

In addition, the following method is used:
Ienumerable <int> getvalues ()
{
Yield return 1;
Yield return 2;
Yield return 3;
Yield return 4;
}
You can use
Foreach (int I in this. getvalues ())
{
Console. writeline (I );
}
For the first time, set the value of 1 for the first yield return, 2 for the second yield return, and so on.

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.