C #2.0 it may be discussed more about generic type, followed by the iterator and anonymous method.
These two features are actually somewhat different in nature. The generic type is implemented by some commands added by Microsoft to Il compared with 1.1.
The iterator is implemented at the compiler level. That is to say, the features of the iterator in C #2.0 are not implemented by introducing Il.
What is an iterator? Here is an example.
For exampleCodeList all files in a specific directory. The code may be written like this.
Public Class C1iterationdemo: ienumerable, ienumerator
{
Ienumerable Member # Region Ienumerable Member
Public Ienumerator getenumerator ()
{
Return This;
}
# Endregion
Ienumerator Member # Region Ienumerator Member
Int Curindex =- 1 ;
Public Void Reset ()
{
Curindex=-1;
}
Public Object Current
{
Get
{
If (Curindex < This . Allfiles. Count)
{
Return This. Allfiles [curindex];
}
Throw New Exception ( " F " );
}
}
Public Bool Movenext ()
{
If ( This . Allfiles. Count = 0 )
Return False ;
Curindex + = 1 ;
If (Curindex = This . Allfiles. Count)
{
Return False;
}
Return True ;
}
# Endregion
Private System. Collections. Specialized. stringcollection allfiles = Null ;
Public C1iterationdemo getfiles ( String Dirpath)
{
Allfiles = New System. Collections. Specialized. stringcollection ();
Allfiles. Clear ();
Foreach ( String F In System. Io. Directory. getfiles (dirpath ))
{
Allfiles. Add (f );
}
Return This ;
}
}
The following is a call:
C1iterationdemo C = New C1iterationdemo (). getfiles ( " C: \ wutemp " );
Foreach ( String S In C)
{
Console. writeline (s );
}
Here, foreach calls the movelast of ienumerator. A call method like foreach is generally an iterator.
If you want to implement similar code, it may be slightly different. In addition, we have not considered sub-directories when enumerating files.
For similar code, we use C #2.0 to make it very simple. I also considered the sub-directory situation.
Public Class Fileutility
{
Public Static Ienumerable < String > Getfiles ( String DIR)
{
Foreach (String File In System. Io. Directory. getfiles (DIR ))
{
YieldReturnFile;
}
Foreach ( String Dir1 In System. Io. Directory. getdirectories (DIR ))
{
Foreach ( String FF In System. Io. Directory. getfiles (dir1 ))
{
YieldReturnFf;
}
}
}
}
Call
Foreach (String F In Fileutility. getfiles ( " C: \ wutemp " ))
{
System. Diagnostics. Debug. writeline (f );
}
Compared with the code, the code below may have several features:
1. The code is concise. In fact, here is an additional yield return statement, because yield return does not correspond to redundant il commands. Therefore, the compiler will generate a class that implements the ienumator interface during compilation and automatically maintain the status of the class. For example, movenext,
2. using yield return can easily implement the iterator in recursive calls. if yield return is not used for the above problems, you can imagine it. you can either temporarily place all the results in an object set. however, this means that the number must be calculated before iteration. or your movenext may be quite complicated .. net compiled code actually uses the state machine. the amount of code is also large.
Similar to iterative calls, for example, it is very convenient to use yield return for binary tree traversal. In addition, the pipeline mode is also very convenient.
However, yield return still has some defects.
For example, if getfiles has a parameter ref or out, it is difficult for the state machine to maintain the state. In fact, yield return does not support methods with ref or out parameters.
More information, please refer:
Iterations with C2:
Http://www.theserverside.net/articles/showarticle.tss? Id = iteratorswithc2
Use anonymous methods and iterationsProgramAnd Department class to create elegant code:
Http://www.microsoft.com/china/msdn/library/langtool/vcsharp/CreElegCodAnymMeth.mspx