2012-06-15 3 views
2

Прежде всего, я уже ищу об этом, но я все еще не могу понять, когда использовать доходность.Доходность не может понять функциональность

Например, у меня есть следующий код:

string[] days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" }; 

public System.Collections.IEnumerator GetEnumerator() 
{ 
    for (int i = 0; i < days.Length; i++) 
    { 
     yield return days[i]; 
    } 
} 

Что бы разница между кодом выше и ниже код?

string[] days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" }; 

public System.Collections.IEnumerator GetEnumerator() 
{ 
    for (int i = 0; i < days.Length; i++) 
    { 
     return days[i]; 
    } 
} 

Не могли бы вы рассказать мне, когда использовать урожай?

+2

Возможный дубликат [Что такое доходность возврата в C#?] (Http://stackoverflow.com/questions/1407162/what-is-yield-return-in-c) –

+0

, который является возможным дубликатом [Что такое ключевое слово yield, используемое для C#?] (http: // stackoverflow.com/questions/39476/what-is-the-yield-keyword-used-for-in-c) :) –

ответ

10

Метод return не помнит, где вы находитесь в своем массиве. Он будет возвращаться в воскресенье каждый раз, когда вы его используете, просто потому, что он начинает этот цикл с нуля каждый раз.

Использование yield более (не менее концептуально) «Я верну это значение, но, в следующий раз, когда вы позвоните мне, я собираюсь подобрать, где я остановился (внутри цикла)».

Подобная вещь может быть сделано в C с использованием статических переменных, чтобы помнить, где вы находитесь:

char *nextDay() { 
    static char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" }; 
    static int nextDay = -1; 
    nextDay = (nextDay + 1) % (sizeof (days)/sizeof (*days)); 
    return days[nextDay]; 
} 

Тот факт, что переменная nextDay сохраняется между вызовами функции означает, что она может быть использована для цикла через массив.

+0

Привет в коде ниже string [] days = {"Sun", "Mon", "Tue »,« Wed »,« Thr »,« Fri »,« Sat »}; общественного System.Collections.IEnumerator GetEnumerator() { для (INT I = 0; я Pinoy2015

+0

@pagodnautak, да, любые ошибки, несмотря на (немного читать код в поле комментариев), то есть ожидаемая функциональность. – paxdiablo

0

Выход взаимодействует с петлями foreach и петлями. Он позволяет каждую итерацию в цикле foreach-loop или for генерировать только при необходимости. Таким образом, он может повысить производительность.

Полный выход из объяснений и его преимуществах можно найти здесь:

http://www.ytechie.com/2009/02/using-c-yield-for-readability-and-performance.html

+0

Было бы более точным сказать, что 'yield' взаимодействует с потребителями' IEnumerable', из которых цикл 'foreach' является лишь обычным примером. Выход также отлично работает, если вы вызываете '.GetEnumerator' самостоятельно и перемещаете его вручную. –

+0

Я полностью согласен с вами. –

4

Некоторые конструкции в C# заставит компилятор превратить код в нечто совсем иное. Оператор yield return вызывает такое преобразование. То, что выглядит как функция, которая выполняет yield return, фактически скомпилирована в класс; многие из локальных переменных в функции преобразуются в поля классов. Сам класс обычно будет реализовывать IEnumerable<T> и IEnumerator<T>. В первый раз вызывается MoveNext, код класса будет запускать часть функции до первого yield return, и отслеживать, с каким номером yield return он попал. В следующий раз, когда он будет вызван, он начнет выполнение там и запустится до следующего yield return. Если есть какие-либо блоки Try/Finally, часть кода в блоке Finally будет выполнена в ответ на IDisposable.Dispose.

Чистый эффект заключается в том, что код, созданный компилятором C# для итератора, почти не будет похож на код, написанный программистом. Причина, по которой это кажется yield return, делает невозможным то, что ее поведение было бы невозможным для чего-либо, даже отдаленно напоминающего вызов метода, но компилятор превращает любую функцию, которая содержит yield return в класс, поведение которого даже не отдаленно напоминает вызов метода.

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