2016-07-03 3 views
4

Что предпочтительнее в этом случае:Доходность в foreach или GetEnumerator()?

IEnumerator<Cat> EnumerateCats() 
{ 
    var rawCats = GetRawCats(); 

    foreach(var cat in rawCats) 
    { 
     var typedCat = new Cat 
     { 
      Name = cat.Key; 
      Breed = cat.Value; 
     }; 

     yield return typedCat; 
    } 
} 

или

IEnumerator<Cat> EnumerateCats() 
{ 
    return GetRawCats() 
     .Select(cat => new Cat 
     { 
      Name = cat.Key; 
      Breed = cat.Value; 
     }) 
     .GetEnumerator(); 
} 

Я предпочитаю последний пример кода. Он работает так же, как и первый?

ответ

5

Я не уверен, почему вам нужно будет вернуть IEnumerator<Cat>. Я бы просто изменить его, чтобы возвращать IEnumerable<Cat>, так что вы можете просто написать:

IEnumerable<Cat> EnumerateCats() 
    => GetRawCats() 
     .Select(cat => new Cat 
     { 
      Name = cat.Key; 
      Breed = cat.Value; 
     }); 
+1

Это легальный код. Мне нужно переопределить существующий метод: virtual IEnumerator EnumerateCats(). – Hopeless

+1

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

0

Вы можете увидеть разницу в написании метода с yield и без него в этом примере

static void Main(string[] args) 
{ 
    foreach (int i in List()) 
    { 
     Console.WriteLine($"In List foreach {i}"); 
    } 
    Console.WriteLine("*****"); 
    foreach (int i in Yield()) 
    { 
     Console.WriteLine($"In Yeild foreach {i}"); 
    } 
} 

private static IEnumerable<int> List() 
{ 
    var inputList = new List <int> { 1, 2, 3 }; 
    List<int> outputlist = new List<int>(); 
    foreach (var i in inputList) 
    { 
     Console.WriteLine($"In List Method {i}"); 
     outputlist.Add(i); 
    } 
     return outputlist.AsEnumerable(); 
} 

private static IEnumerable<int> Yield() 
{ 
    var inputList = new List<int> { 1, 2, 3 }; 
    foreach (var i in inputList) 
    { 
     Console.WriteLine($"In Yield Method {i}"); 
     yield return i; 
    } 
} 

Вот выход:

In List Method 1 
In List Method 2 
In List Method 3 
In List foreach 1 
In List foreach 2 
In List foreach 3 
***** 
In Yield Method 1 
In Yield foreach 1 
In Yield Method 2 
In Yield foreach 3 
In Yield Method 3 
In Yield foreach 3 
+0

В OP-коде нет такой разницы. В обоих случаях OP возвращает ленивую перечислимую коллекцию. – PetSerAl

-1

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

Смежные вопросы