C# IEnumerable<;T>;空合并扩展

C# IEnumerable<;T>;空合并扩展,c#,extension-methods,ienumerable,null-coalescing,C#,Extension Methods,Ienumerable,Null Coalescing,我经常遇到这样的问题:在通过foreach或LINQ查询对IEnumerable进行迭代之前,检查它是否为null,然后我经常遇到这样的代码: var myProjection = (myList ?? Enumerable.Empty<T>()).Select(x => x.Foo)... var myProjection=(myList??Enumerable.Empty())。选择(x=>x.Foo)。。。 因此,我想将此扩展方法添加到扩展类: public stat

我经常遇到这样的问题:在通过foreach或LINQ查询对
IEnumerable
进行迭代之前,检查它是否为null,然后我经常遇到这样的代码:

var myProjection = (myList ?? Enumerable.Empty<T>()).Select(x => x.Foo)...
var myProjection=(myList??Enumerable.Empty())。选择(x=>x.Foo)。。。
因此,我想将此扩展方法添加到扩展类:

public static class MyExtensions 
{
    public static IEnumerable<T> AsEmptyIfNull<T>(this IEnumerable<T> source)
    {
        return source ?? Enumerable.Empty<T>();
    }
}
公共静态类MyExtensions
{
公共静态IEnumerable AsEmptyIfNull(此IEnumerable源)
{
返回源??可枚举的.Empty();
}
}
看着这段代码,我马上想到了一个小问题,也就是说,考虑到扩展方法的“实例方法方面”,它应该仅仅作为一个静态方法来实现,否则类似这样的东西是完全合法的:

IEnumerable<int> list = null;
list.AsEmptyIfNull();
IEnumerable list=null;
list.AsEmptyIfNull();
您认为使用它还有其他缺点吗?
如果大量使用,这种扩展是否会导致开发人员出现某种不良趋势


奖金问题:

你能给它起个更好的名字吗<代码>:)
(英语不是我的第一语言,那么我不太擅长命名…)


提前感谢。

返回
IEnumerable
的方法应该返回空值,而不是空值。所以你不需要这个

见这个问题:


否则,您的代码看起来是正常的。

如果您可以控制它,那么返回一个
null
而不是一个空序列通常不是一个好主意。这是不言自明的,如果您认为当有人被要求生成一个集合时,返回<代码> null 并不是说“集合是空的”,而是“根本没有这样的集合”。 如果您拥有返回可枚举项的方法,那么返回空的
IEnumerable
(如果返回很多,它甚至可以是一个特殊用途的只读静态对象)就是一种方法


如果您被迫使用一个坏习惯的库,这种库在这种情况下会返回
null
,那么这种扩展方法可能是一种解决方案,但我还是不喜欢它。也许最好在你自己的版本中包装那些不礼貌的方法,在人们看不到的地方进行合并。通过这种方式,您既可以方便地始终使用可枚举而不是
null
,也可以正确地不支持“return null”范式。

是的,这是正确的,但并非总是可以更改代码以获得此结果(例如,在使用API时)。举一个真实的例子,尝试用protobuf序列化一个空列表,然后反序列化它:您将得到null:)问题是什么?难道你不想合法吗?使用静态方法也是合法的,但我认为重点是使其合法,使用扩展或静态方法也是如此。@recursive:您是指“小问题”部分还是整个问题?如果是前者,我只是觉得对于“习惯使用实例方法”的人来说,阅读代码可能有点奇怪。如果是后者,那么我的问题正是关于推广这种扩展方法的正确性(例如在公司共享的实用程序组件中),因为这可能会导致不良行为……是的,可能最好的方法是包装不良的库。无论如何,创建这种扩展似乎没有那么有害,是吗?@digEmAll:有害之处在于,看到它的人可能会认为方法返回
null
而不是空集合并编写自己的此类方法是可以的,这会使问题永久化。除此之外,我看不出有什么害处。