Если вы вызываете метод расширения IgnoreNullItems
в коде выборки ниже, отложенное выполнение работает, как и ожидалось, однако при использовании IgnoreNullItemsHavingDifferentBehaviour
исключение возникает немедленно.Почему?
List<string> testList = null;
testList.IgnoreNullItems(); //nothing happens as expected
testList.IgnoreNullItems().FirstOrDefault();
//raises ArgumentNullException as expected
testList.IgnoreNullItemsHavingDifferentBehaviour();
//raises ArgumentNullException immediately. not expected behaviour ->
// why is deferred execution not working here?
Спасибо, что поделились своими идеями!
Раффаэль Загет
public static class EnumerableOfTExtension
{
public static IEnumerable<T> IgnoreNullItems<T>(this IEnumerable<T> source)
where T: class
{
if (source == null) throw new ArgumentNullException("source");
foreach (var item in source)
{
if (item != null)
{
yield return item;
}
}
yield break;
}
public static IEnumerable<T> IgnoreNullItemsHavingDifferentBehaviour<T>(
this IEnumerable<T> source)
where T : class
{
if (source == null) throw new ArgumentNullException("source");
return IgnoreNulls(source);
}
private static IEnumerable<T> IgnoreNulls<T>(IEnumerable<T> source)
where T : class
{
foreach (var item in source)
{
if (item != null)
{
yield return item;
}
}
yield break;
}
}
Вот версия с таким же поведением:
Здесьверсия, которая показывает то же поведение.В этом случае не позволяйте resharper «улучшать» оператор foreach;) -> resharper меняет foreach на версию «IgnoreNullItemsHavingDifferentBehaviour» с оператором return.
public static IEnumerable<T> IgnoreNullItemsHavingSameBehaviour<T>(this IEnumerable<T> source) where T : class
{
if (source == null) throw new ArgumentNullException("source");
foreach (var item in IgnoreNulls(source))
{
yield return item;
}
yield break;
}