Обновление : Ваша проблема не связана конкретно с ключевым словом yield
. Это связано с дисперсией типа .
Ваш метод AcceptChangesAndYield
возвращает объект типа, реализующего IEnumerable<MyModels.Interfaces.ILookup>
(на самом деле это тип, сгенерированный компилятором, но это не очень важно). В своем вызове метода вы пытаетесь уменьшить до IEnumerable<MyModels.StatusLookup>
, что более конкретно .
Интерфейс IEnumerable<T>
имеет ковариант , что позволит вам upcast до менее специфичного типа; например, вы можете привести от List<string>
к IEnumerable<object>
(в любом случае в .NET 4.0). Тип, сгенерированный компилятором для предоставления возвращаемого значения вашего метода AcceptChangesAndYield
, реализует только IEnumerable<MyModels.Interfaces.ILookup>
, поэтому вы можете преобразовать результат в IEnumerable<object>
(например), но не в IEnumerable<MyModels.StatusLookup>
.
К счастью, решение довольно простое. Переопределите ваш AcceptChangesAndYield
метод следующим образом:
// Note: We are using a generic type constraint on T.
public static IEnumerable<T> AcceptChangesAndYield<T>(this IEnumerable<T> obj)
where T : MyModels.Interfaces.ILookup
{
if (obj.IsNull()) yield break;
foreach (var m in obj)
{
// Did you mean to put m.AcceptChanges() here?
yield return m;
}
}
Это, в свою очередь, позволит реализовать ваш метод GetAll
следующим образом:
public IEnumerable<MyModels.StatusLookup> GetAll()
{
var results = Database.Current.pStatusLookupLoadAll()
.ExecuteTypedList<MyModels.StatusLookup>();
// Note: no need for a cast, as the return value is now
// already strongly typed as IEnumerable<MyModels.StatusLookup>.
return results.AcceptChangesAndYield();
}
Оригинальный ответ : Кажется, вы просто хотите этого?
IEnumerable<T> EnumerateResults<T>(IEnumerable<T> results)
{
if (results.IsNull()) yield break;
foreach (T result in results)
{
// ..Common logic lines...
yield return result;
}
}
Тогда в вашем коде, где вы хотите удалить дублирование, у вас будет просто:
// Specific stuff
var results = BlahBlahBlah();
// Common stuff
return EnumerateResults(results);
Правильно? Или я неправильно понимаю вашу проблему?