C# 检查列表中元素的更好方法?

C# 检查列表中元素的更好方法?,c#,.net,linq,linq-to-objects,C#,.net,Linq,Linq To Objects,如果我想执行诸如.Where(…)或.Max(…)之类的操作,我需要确保列表不为null且计数大于零。除了每次使用列表时都要执行以下操作外: if(mylist != null && mylist.Count > 0) {...} 我可以使用更内联的或类似lambda的技术吗?或者另一种更为压缩的技术?您可以尝试myList.Any()而不是.Count,但是您仍然需要检查null不要让列表为null 确保对象始终处于有效状态。通过确保列表从不为空,您永远不必检查列表是否

如果我想执行诸如.Where(…)或.Max(…)之类的操作,我需要确保列表不为null且计数大于零。除了每次使用列表时都要执行以下操作外:

if(mylist != null && mylist.Count > 0)
{...}

我可以使用更内联的或类似lambda的技术吗?或者另一种更为压缩的技术?

您可以尝试
myList.Any()
而不是
.Count
,但是您仍然需要检查
null

不要让列表为null

确保对象始终处于有效状态。通过确保列表从不为空,您永远不必检查列表是否为空

public class MyClass
{
    private readonly IEnumerable<int> ints;

    public MyClass(IEnumerable<int> ints)
    {
        this.ints = ints;
    }

    public IEnumerable<int> IntsGreaterThan5()
    {
        return this.ints.Where(x => x > 5);
    }
}
因此,运行Max并检查是否返回空值或整数。瞧

其他选项

自定义扩展方法

您还可以编写自己的扩展方法

public static MinMaxHelper()
{
    public static int? MaxOrDefault(IEnumerable<int> ints)
    {
        if(!ints.Any())
        {
            return null;
        }

        return ints.Max();
    }

    public static int MaxOrDefault(IEnumerable<int> ints, int defaultValue)
    {
        if(!ints.Any())
        {
            return defaultValue;
        }

        return ints.Max();
    }
}
publicstaticminmaxhelper()
{
公共静态整数?MaxOrDefault(IEnumerable整数)
{
如果(!int.Any())
{
返回null;
}
返回int.Max();
}
公共静态int MaxOrDefault(IEnumerable int,int defaultValue)
{
如果(!int.Any())
{
返回默认值;
}
返回int.Max();
}
}
重写Linq扩展方法


最后,请记住,内置Linq扩展方法可以使用您自己的具有匹配签名的扩展方法覆盖。因此,您可以编写一个扩展方法来替换.Where(…)和.Max(…)以返回null(或默认值),而不是在枚举为null时抛出ArgumentNullException。

如果列表存在null的风险,则在调用它的任何方法之前,您都必须检查该方法,但您可以使用any()方法而不是计数。无论列表中是否有一个或多个项目,只要对一个项目进行计数,就会返回true。这样可以避免对整个列表进行迭代,而Count将执行以下操作:

if(mylist != null && mylist.Any())
{...}

使用
empty
集合而不是
null
集合
Where
可以很好地处理空集合,因此在调用它之前不需要确保
Count>0
。如果您先调用,还可以对空集合调用
Max

对于
IEnumerable
使用
Enumerable.Empty()

对于
T[]
使用
newt[0]


对于
列表
使用
新列表()

您可以使用??将null转换为右侧提供的值的运算符:

public ProcessList(IEnumerable<int> ints)
{
    this.ints = ints ?? new List<int>();
}
公共进程列表(IEnumerable int)
{
this.ints=ints??新列表();
}

顺便说一句:使用LINQ处理空列表不是问题。

您不需要选中
Count
来调用
Where
Max
需要值类型的非空列表,但这可以通过内联转换来克服,例如

int? max = new List<int>().Max(i => (int?)i); // max = null
int?max=新列表().max(i=>(int?)i);//max=null

我的一般偏好是使用空列表实例,而不是空列表变量。然而,并不是每个人都能诱使他们的同事参与这一安排。您可以使用此扩展方法保护自己不受空列表变量的影响

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

大多数linq方法在空集合上工作。有两个方法不是最小值和最大值。通常,我对一个iGroup调用这些方法。大多数iGroup实现至少有一个元素(例如,由
GroupBy
ToLookup
生成的iGroup)。对于其他情况,可以使用
Enumerable.DefaultIfEmpty

int result = myList.EmptyIfNull().Select(c => c.FavoriteNumber).DefaultIfEmpty().Max();

你在回答这个问题吗?对不起,我今天一定很糟糕。我最近在while循环中看到了很多空检查和列表实例化,而不仅仅是用class.IMHO实例化列表,像list这样的对象永远不应该为空。如果它们是类成员,我总是初始化它们,如果它们是从我自己创建的函数返回的,我确保该函数返回一个空列表而不是null。答案可能重复:您可以始终编写自己的扩展方法来使用Where()或Max()等操作这将包括在使用实际扩展方法之前的null和Count测试。Drews answer与
myList.Max(x=>new int?(x))
结合使用,将满足您的需要。此条件的作用是什么
!项目。任何()?@sll,不,如果源为null,Any()将抛出ArgumentNullException。@sll,我不明白你的问题。
Any(…)
Linq扩展方法将检查枚举中包含的任何项是否满足条件。如果没有提供任何条件参数,它只需检查枚举是否包含任何元素<代码>!items.Any()
如果列表为空,则为true,否则为false。所有这些对我来说都是干净的,对我来说不清楚。如果源为null,您的第一个答案
Any()将抛出ArgumentNullException。
在下面的代码
items.Any()
中千万不要抛出这样的异常,因为在我们有条件
items==null
正确之前,所以您仍然需要检查null。
int? max = new List<int>().Max(i => (int?)i); // max = null
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source)
{
  return source ?? Enumerable.Empty<T>();
}
Customers result = myList.EmptyIfNull().Where(c => c.Name == "Bob");
int result = myList.EmptyIfNull().Select(c => c.FavoriteNumber).DefaultIfEmpty().Max();