如果您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 使用 return 语句将 foreach 更改为“IgnoreNullItemsHavingDifferentBehaviour”版本。
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;
}