Csharp/CSharp Tutorial/Data Structure/yield

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

Simple Iterator

<source lang="csharp">using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text;

   class Program
   {
       public static IEnumerable SimpleList()
       {
           yield return "string 1";
           yield return "string 2";
           yield return "string 3";
       }
       public static void Main(string[] args)
       {
           foreach (string item in SimpleList())
               Console.WriteLine(item);
       }
   }</source>

Skip the foreach and manually use the enumerable and enumerator for a "yield" IEnumerable

<source lang="csharp">using System; using System.Collections.Generic; class LetterCollection {

  string[] letters ={ "A", "B", "C"};
  
  public IEnumerable<string> Forward()                       
  {
     for (int i = 0; i < letters.Length; i++)
        yield return letters[i];
  }

} class MainClass {

  static void Main()
  {
     LetterCollection cc = new LetterCollection();
     
     IEnumerable<string> ieable = cc.Forward();
     IEnumerator<string> ieator = ieable.GetEnumerator();
     while (ieator.MoveNext())
        Console.Write("{0} ", ieator.Current);
  }

}</source>

A B C

Use multiple yield statements

<source lang="csharp">using System; using System.Collections;

class MyClass {

 public IEnumerator GetEnumerator() { 
   yield return "A"; 
   yield return "B"; 
   yield return "C"; 
   yield return "D"; 
   yield return "E"; 
 } 

}

class MainClass {

 public static void Main() { 
   MyClass mc = new MyClass(); 

   foreach(char ch in mc) 
     Console.Write(ch + " "); 

   Console.WriteLine(); 
 } 

}</source>

A B C D E

Use yield break

<source lang="csharp">using System; using System.Collections;

class MyClass {

 char ch = "A"; 

 public IEnumerator GetEnumerator() { 
   for(int i=0; i < 26; i++) { 
     if(i == 10) 
        yield break; // stop iterator early 
     yield return (char) (ch + i); 
   } 
 } 

}

class MainClass {

 public static void Main() { 
   MyClass mc = new MyClass(); 

   foreach(char ch in mc) 
     Console.Write(ch + " "); 

   Console.WriteLine(); 
 } 

}</source>

A B C D E F G H I J

Yield Break And Try Finally

<source lang="csharp">using System; using System.Collections.Generic; using System.Threading; using System.ruponentModel;

   class MainClass{
       static IEnumerable<int> CountWithTimeLimit(DateTime limit){
           try{
               for (int i = 1; i <= 5; i++){
                   if (DateTime.Now >= limit){
                       yield break;
                   }
                   yield return i;
               }
           }finally{
               Console.WriteLine("Stopping!");
           }
       }
       static void Main(){
           DateTime stop = DateTime.Now.AddSeconds(20);
           foreach (int i in CountWithTimeLimit(stop))
           {
               Console.WriteLine("Received {0}", i);
               Thread.Sleep(100);
           }
       }
   }</source>

yield IEnumerable data

<source lang="csharp">using System; using System.Collections.Generic; class LetterCollection {

  string[] letters ={ "A", "B", "C"};
  
  public IEnumerable<string> Forward()                       
  {
     for (int i = 0; i < letters.Length; i++)
        yield return letters[i];
  }

} class MainClass {

  static void Main()
  {
     LetterCollection cc = new LetterCollection();
     foreach (string color in cc.Forward())
        Console.Write("{0} ", color);
     Console.WriteLine("");
  }

}</source>

A B C

Yield with Break

<source lang="csharp">using System; using System.Collections.Generic; using System.Threading; using System.ruponentModel;

   class MainClass
   {
       static IEnumerable<int> CountWithTimeLimit(DateTime limit)
       {
           for (int i = 1; i <= 5; i++)
           {
               if (DateTime.Now >= limit)
               {
                   yield break;
               }
               yield return i;
           }
       }
       static void Main()
       {
           DateTime stop = DateTime.Now.AddSeconds(2);
           foreach (int i in CountWithTimeLimit(stop))
           {
               Console.WriteLine("Received {0}", i);
               Thread.Sleep(100);
           }
       }
   }</source>