gpt4 book ai didi

任何 IEnumerable 的 C# EmptyIfNull 扩展返回空派生类型

转载 作者:行者123 更新时间:2023-11-30 13:36:22 25 4
gpt4 key购买 nike

假设 null 和空集合是等价的,我正在尝试为 IEnumerable 类型编写一个扩展方法以返回派生类型的空集合而不是 null。这样我就不必到处重复空值检查,也不会得到必须强制转换的 IEnumerable。

例如

List<Foo> MethodReturningFooList()
{
...
}

Foo[] MethodReturningFooArray()
{
...
}

void Bar()
{
List<Foo> list = MethodReturningFooList().EmptyIfNull();
Foo[] arr = MethodReturningFooArray().EmptyIfNull();
}

public static class Extension
{
public static T EmptyIfNull<T>(this T iEnumerable)
where T : IEnumerable, new()
{
var newTypeFunc = Expression.Lambda<Func<T>>(Expression.New(typeof(T))).Compile();
return iEnumerable == null ? newTypeFunc() : iEnumerable;
}
}

此扩展程序似乎有效,但有人发现任何陷阱吗?

最佳答案

是的,在这种情况下它会中断:

IEnumerable<int> test = null;
var result = test.EmptyIfNull();

你可以这样解决:

public static class Extension
{
public static List<T> EmptyIfNull<T>(this List<T> list)
{
return list ?? new List<T>();
}
public static T[] EmptyIfNull<T>(this T[] arr)
{
return arr ?? new T[0];
}
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> enumerable)
{
return enumerable ?? Enumerable.Empty<T>();
}
}

您需要重载以确保返回相同的集合类型(与之前一样)。

这是一个不能返回相同集合类型的例子:

public abstract class MyAbstractClass : IEnumerable<int>
{
private List<int> tempList = new List<int>();
public IEnumerator GetEnumerator()
{
return tempList.GetEnumerator();
}
IEnumerator<int> IEnumerable<int>.GetEnumerator()
{
return tempList.GetEnumerator();
}
}

MyAbstractClass myClass = null;
MyAbstractClass instance = myClass.EmptyIfNull();

我们无法返回 MyAbstractClass在这里不知道子类。对于空引用,不猜测是不可能的。此外,当类没有默认构造函数时会发生什么?进入危险区域。

您需要一个包罗万象的 IEnumerable<T>返回,并让用户转换它,或者像我上面显示的那样提供重载

关于任何 IEnumerable 的 C# EmptyIfNull 扩展返回空派生类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34645963/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com