Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为null IEnumerables上的Count()返回零_C#_.net_Collections - Fatal编程技术网

C# 为null IEnumerables上的Count()返回零

C# 为null IEnumerables上的Count()返回零,c#,.net,collections,C#,.net,Collections,我已经厌倦了使用这样的代码: var count = 0; if (myEnumerable != null) { count = myEnumerable.Count(); } 这有点迂腐: var count = (myEnumerable ?? new string[0]).Count(); 有没有更整洁的方法?我曾经在IEnumerable上有一个(名字不好的)PhantomCount扩展方法,它使用了我的第一个代码示例,但它有一种气味(除了名称之外)。怎么样 count =

我已经厌倦了使用这样的代码:

var count = 0;
if (myEnumerable != null)
{
    count = myEnumerable.Count();
}
这有点迂腐:

var count = (myEnumerable ?? new string[0]).Count();
有没有更整洁的方法?我曾经在IEnumerable上有一个(名字不好的)PhantomCount扩展方法,它使用了我的第一个代码示例,但它有一种气味(除了名称之外)。

怎么样

count = myEnumerable == null? 0 : myEnumerable.Count()

问题实际上在于创建这些可枚举的内容。除非您有很好的理由,否则生成iterable集合的任何内容都应该返回空集合,而不是
null
。这将与目标一致,因此好处是相同的


我的建议是修复生成myEnumerable的任何内容,或者如果您不能做到这一点,请在前面添加一个检查方法,查看它是否为null并做出适当的反应。

我不认为使用扩展方法是一个坏主意

public static int NullableCount<T>(this IEnumerable<T> collection)
{
   return collection == null ? 0 : collection.Count();
}
public static int NullableCount(此IEnumerable集合)
{
return collection==null?0:collection.Count();
}

只需创建自己的扩展方法,根据需要处理空枚举

public int CountOrNull<T>(this IEnumerable<T> source)
{
    return source == null ? 0 : source.Count();
}

这就是扩展方法的优点。即使调用方法的对象是
null

我也会编写自己的扩展方法
CountOrZeroForNull
,如其他答案所示,它们仍然可以正常工作

此外。。。而不是:

var count = (myEnumerable ?? new string[0]).Count();
                          // ^^^^^^^^^^^^^
你可以写:

var count = (myEnumerable ?? Enumerable.Empty<string>()).Count();
                          // ^^^^^^^^^^^^^^^^^^^^^^^^^^
var count=(myEnumerable??Enumerable.Empty()).count();
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
这并不能缓解您的特定问题,但它可以避免分配未使用的数组。(
Enumerable.Empty
最有可能实现为一个简单的
yielbreak
语句。)


虽然它没有其他答案那么专业,但它是最具可读性的。

如果返回的值为0,您将采取什么措施

如果这是有趣的,也许您应该使用Haack的
IsNullOrEmpty
扩展方法来扩展
IEnumerable
,如下所示:

public static bool IsNullOrEmpty<T>(this IEnumerable<T> items) 
{
    return items == null || !items.Any();
}

我使用自定义扩展方法:

public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source)
{
    return source ?? Enumerable.Empty<T>();
}

...

int count = myEnumerable.EmptyIfNull().Count();
公共静态IEnumerable EmptyIfNull(此IEnumerable源代码)
{
返回源??可枚举的.Empty();
}
...
int count=myEnumerable.EmptyIfNull().count();

2019年,最整洁的方法是
var count=myEnumerable?.count()??0;

2021年编辑:

public int CountNullable(此IEnumerable?可枚举)=>
可枚举?.Count()??0;

我有一种感觉,他会要求一个比这个更整洁的,+1尽管如此:)+1我做了完全一样的东西——只是把它命名为
CountOrZero
。我个人认为这更清楚。
Enumerable.Empty
的当前实现实际上返回一个单例空
T[]
数组。@LukeH:我不会想到的。感谢您查找。我不认为这三行代码比一个命名良好的扩展方法更具可读性。是的,我希望避免多次重复相同的检查。这就是我的问题所在。@Noldorin:修复了代码示例中的一个打字错误(注释
//4
);也许可以证实这确实是你想要的。@stakx:谢谢;这确实是一个输入错误。请再输入+1。当设计一个API来返回空集合而不是空集合时,这是一个很好的实践,以避免给开发人员带来负担,让他们一直这样做。爱尔兰出产的所有优质葡萄酒列表(空列表)与纳尼亚出产的所有优质葡萄酒列表(空列表,因为纳尼亚不存在)之间存在差异。有时有必要区分空和空。我同意应该倾向于返回空的状态。@Jon:使用null来表示特殊情况就像汽车踩下手刹来表示汽油不足。@Anon使用null来表示空的状态就像,呃,一些非常明显、直接和明智的事情。@Dan。我不同意,我不认为null是无效状态的良好指示器。当“enumerable不存在”和“enumerable存在且为空”都有效并且可以有目的地加以区分时,它是一个很好的指示器。当它们都有效但没有实际差异时,空对象模式中的空枚举会摇动(我最喜欢的一个),当其中一个无效时,我会抛出一个异常。所有这三种情况都可以在经过深思熟虑的代码中发生。+1,我认为这是列出的扩展方法解决方案中最干净的。非常明确的一点是,您假设一个空的可枚举项为空,然后您可以像往常一样处理该可枚举项。
public static bool IsNullOrEmpty<T>(this IEnumerable<T> items) 
{
    return items == null || !items.Any();
}
public class ArgumentNullOrEmptyException : ArgumentNullException
{
    public ArgumentNullOrEmptyException( string paramName ) : base( paramName )
    {}

    public ArgumentNullOrEmptyException( string paramName, string message ) : base( paramName, message )
    {}

    public override string Message
    {
        get
        {
            return "Value cannot be null nor empty.{0}Parameter name: {1}".FormatWith( Environment.NewLine, ParamName );
        }
    }
}
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source)
{
    return source ?? Enumerable.Empty<T>();
}

...

int count = myEnumerable.EmptyIfNull().Count();