Я знаю, что это старый вопрос, но я хотел бы предложить один пример того, как можно творчески использовать ключевое слово yield. Я действительно извлек выгоду из этой техники. Надеюсь, это поможет любому, кто наткнется на этот вопрос.
Примечание: не думайте о ключевом слове yield как о другом способе создания коллекции. Большая часть мощности yield заключается в том, что выполнение в вашем методе или свойстве приостанавливается до тех пор, пока вызывающий код не выполнит итерацию следующего значения. Вот мой пример:
Использование ключевого слова yield (наряду с реализацией сопрограмм Caliburn.Micro Роба Айзенбурга ) позволяет мне выразить асинхронный вызов веб-службы следующим образом:
public IEnumerable<IResult> HandleButtonClick() {
yield return Show.Busy();
var loginCall = new LoginResult(wsClient, Username, Password);
yield return loginCall;
this.IsLoggedIn = loginCall.Success;
yield return Show.NotBusy();
}
Для этого нужно включить мой BusyIndicator, вызвать метод Login в моей веб-службе, установить для моего флага IsLoggedIn возвращаемое значение, а затем снова отключить BusyIndicator.
Вот как это работает: IResult имеет метод Execute и событие Completed. Caliburn.Micro извлекает IEnumerator из вызова HandleButtonClick () и передает его в метод Coroutine.BeginExecute. Метод BeginExecute начинает перебирать IResults. Когда возвращается первый IResult, выполнение приостанавливается внутри HandleButtonClick (), и BeginExecute () присоединяет обработчик события к событию Completed и вызывает Execute (). IResult.Execute () может выполнять либо синхронную, либо асинхронную задачу и запускает событие Completed, когда оно выполнено.
LoginResult выглядит примерно так:
public LoginResult : IResult {
// Constructor to set private members...
public void Execute(ActionExecutionContext context) {
wsClient.LoginCompleted += (sender, e) => {
this.Success = e.Result;
Completed(this, new ResultCompletionEventArgs());
};
wsClient.Login(username, password);
}
public event EventHandler<ResultCompletionEventArgs> Completed = delegate { };
public bool Success { get; private set; }
}
Это может помочь настроить что-то вроде этого и пройти через выполнение, чтобы посмотреть, что происходит.
Надеюсь, это поможет кому-то! Я действительно любил исследовать различные способы, которыми можно использовать урожай.
yield
привязанIEnumerable<T>
и к своему виду. Это в некотором роде ленивая оценка