2016-05-21 2 views
0

Мне было интересно, когда yield было бы полезно. Мне кажется, что я могу использовать Linq каждый раз, когда могу использовать yield.Полезность доходности

Скажем, у меня есть этот тест класс

public class Test 
{ 
    public object Test1; 
    public object Test2; 

    public Test(object test1, object test2) 
    { 
     this.Test1 = test1; 
     this.Test2 = test2; 
    } 
} 

А те два DataTable s

DataTable dt1 = new DataTable(); 
dt1.Columns.Add("test1", typeof(string)); 
dt1.Columns.Add("test2", typeof(string)); 
dt1.Rows.Add("a1", "a2"); 
dt1.Rows.Add("b1", "b2"); 

DataTable dt2 = new DataTable(); 
dt2.Columns.Add("test1", typeof(string)); 
dt2.Columns.Add("test2", typeof(string)); 
dt2.Rows.Add("c1", "c2"); 
dt2.Rows.Add("d1", "d2"); 

Пример 1

Если я хочу, чтобы получить IEnumerable<Test> для DT1 I может сделать

IEnumerable<Test> GetTests(DataTable dt) 
{ 
    foreach (DataRow row in dt.Rows) 
    { 
     yield return new Test(row["test1"], row["test2"]); 
    } 
} 

IEnumerable<Test> tests = GetTests(dt1); 

Но я мог бы просто сделать

IEnumerable<Test> testsLinq = dt1.Rows.OfType<DataRow>() 
             .Select(row => new Test(row["test1"], row["test2"])); 

Пример 2

Другой yield использование я знаю, чтобы объединить

IEnumerable<Test> MergeTests(DataTable dt1, DataTable dt2) 
{ 
    foreach (DataRow row in dt1.Rows) 
    { 
     yield return new Test(row["test1"], row["test2"]); 
    } 

    foreach (DataRow row in dt2.Rows) 
    { 
     yield return new Test(row["test1"], row["test2"]); 
    } 
} 

IEnumerable<Test> mergedTests = MergeTests(dt1, dt2); 

Но опять же, я мог бы сделать

IEnumerable<Test> mergedTestsLinq = dt1.Rows.OfType<DataRow>() 
              .Select(row => new Test(row["test1"], row["test2"])) 
              .Union(dt2.Rows.OfType<DataRow>() 
                  .Select(row => new Test(row["test1"], row["test2"]))); 

Есть ли какой-либо случай Мне неизвестно, где yield лучше всего использовать в течение Linq?

+1

Возможно, вы найдете здесь несколько ответов: https://stackoverflow.com/questions/39476/what-is-the-yield-keyword-used-for-in-c?rq=1 – ciscoheat

+0

@ciscoheat Я видел это post, но 'yield' с' if 'можно сделать с помощью' .Where(). Select() ' –

+0

LINQ, вероятно, использует« выход »для выполнения своей работы внутренне, по крайней мере, по комментариям в этом сообщении. –

ответ

1

yield return намного более гибкий, если структура данных не является линейной.

Например, вы можете использовать его, чтобы перечислить дерево в предзаказе, postorder или заказовМой:

IEnumerable<T> InorderTree<T>(TreeNode<T> node) { 
    if (node.Left != null) { 
     foreach (var x in InorderTree(node.Left)) { 
      yield return x; 
     } 
    } 
    if (node.Right != null) { 
     foreach (var x in InorderTree(node.Right)) { 
      yield return x; 
     } 
    } 
    yield return node.Value; 
} 

Вы также мог бы производить метод, который дает последовательность чисел Фибоначчей:

IEnumerable<int> Fibonacci(int n) { 
    int first = 0, second = 1; 
    for (int c = 0 ; c < n ; c++) { 
     int next; 
     if (c <= 1) { 
      next = c; 
     } else { 
      next = first + second; 
      first = second; 
      second = next; 
     } 
     yield return next; 
    } 
} 
Смежные вопросы