c# - чего - зачем нужен zennoposter




Доходность возвращается много? (4)

Вы можете разбить свой метод на два. Учитывая эти методы расширения:

public static class MultiEnumerableExtensions {
  public static IEnumerable<T> Pack<T>(this T item) {
    yield return item;
  }
  public static IEnumerable<T> Flatten<T>(
    this IEnumerable<IEnumerable<T>> multiList) {
    return multiList.SelectMany(x => x);
  }
}

И используя example Эрика Липперта, он становится следующим:

public static class BinaryTreeExtensions {
  public static IEnumerable<T> PreorderTraversal<T>(this BinaryTree<T> root) {
    return PreorderTraversalMulti(root).Flatten();
  }
  private static IEnumerable<IEnumerable<T>> PreorderTraversalMulti<T>(
    this BinaryTree<T> root) {
    if (root == null) yield break;
    yield return root.Item.Pack(); // this packs an item into an enumerable
    yield return root.Left.PreorderTraversal();
    yield return root.Right.PreorderTraversal();
  }
}

Внутренний метод дает перечисления T вместо Ts, а внешний метод просто должен сгладить этот результат.

Я нахожусь слишком много для IEnumerables, чтобы я мог возвращать каждый результат. Есть ли способ сжать что-то вроде этого

foreach (var subSelector in subSelectors)
{
    foreach (var node in FindSingle(context, subSelector))
        yield return node;
} 

Чтобы удалить внутренний foreach?


Использовать Enumerable.SelectMany :

return subSelectors.SelectMany(subselector => FindSingle(context, subSelector));

Это работает только в том случае, если в вашем методе нет других операторов возврата доходности.


Нет, нет, если вы полностью не замените каждый yield return с помощью одного оператора return использующего LINQ.

Например:

return someSet
    .Concat(someOtherSet.SelectMany(s => FindSingle(context, s));

Это несколько часто запрашиваемая функция, которую C # не поддерживает. См. Этот элемент Connect для получения дополнительной информации:

http://connect.microsoft.com/VisualStudio/feedback/details/256934/yield-return-to-also-yield-collections

Предложенный синтаксис обычно выглядит примерно так:

public static IEnumerable<T> PreorderTraversal<T>(this BinaryTree<T> root)
{
    if (root == null) yield break;
    yield return root.Item;
    yield foreach root.Left.PreorderTraversal();
    yield foreach root.Right.PreorderTraversal();
}

Если вы заинтересованы в игре на языке C #, который поддерживает эту функцию, взгляните на Cω:

http://research.microsoft.com/en-us/um/cambridge/projects/comega/

Вы также можете прочитать эту статью об этой функции разработчиками Cω:

http://research.microsoft.com/en-us/projects/specsharp/iterators.pdf

Если вас интересует не-C # -подобный язык, который поддерживает эту функцию, взгляните на «выход!». функция F #. (Мне просто нравится, что название этой функции - «выход!»)

Даже если вас не интересуют теоретические материалы, похоже, что вы столкнулись с этой ситуацией как практическая проблема. Вы также должны прочитать статью Уэса Дайера о методах эффективного выполнения такой вложенной итерации без «yield foreach»:

http://blogs.msdn.com/b/wesdyer/archive/2007/03/23/all-about-iterators.aspx





c#