C# linq筛选器在默认值之后无法显示?

C# linq筛选器在默认值之后无法显示?,c#,linq,C#,Linq,我一直在尝试用LINQ重写一些命令式代码,直到我意识到我遗漏了什么。但我不知道为什么这是一个问题。考虑下面的问题。运行test.Test2(testList)时,测试失败 序列不包含匹配的元素 在过去,我互换地处理这些形式,通过将谓词推到第一个,单个,等等,来编写更小的代码。。。条款。显然,当涉及DeafultIfEmpty时,我不能这样做。这是因为使用Where和First、Single等不能互换吗?或者,这是因为DefaultIfEmpty子句引入了一种复杂性吗 编辑1 我添加了一个测试来显

我一直在尝试用LINQ重写一些命令式代码,直到我意识到我遗漏了什么。但我不知道为什么这是一个问题。考虑下面的问题。运行
test.Test2(testList)
时,测试失败

序列不包含匹配的元素

在过去,我互换地处理这些形式,通过将谓词推到
第一个
单个
,等等,来编写更小的代码。。。条款。显然,当涉及
DeafultIfEmpty
时,我不能这样做。这是因为使用
Where
First
Single
等不能互换吗?或者,这是因为
DefaultIfEmpty
子句引入了一种复杂性吗

编辑1 我添加了一个测试来显示FirstOrDefault不起作用。它因“未找到”不等于(null)而失败


您应该使用
FirstOrDefault()
,这样当数组不匹配时,将返回默认值,而不是引发异常


编辑:

Test1
中,在
Where
子句之后,结果序列变为空。应用
DefaultIfEmpty
时,生成的序列将包含单个元素
“未找到”


Test2
中,当应用
DefaultIfEmpty
时,序列尚未过滤。因此,相同的序列被传递。然而,当代码>第一(谓词)试图减少序列时,没有什么可以出现,这就是为什么代码>无效操作异常>代码>发生。

< P> > LINQ方法的顺序很重要,考虑每种方法对输入枚举的作用(<代码> {橙子”、“梨”、“菠萝”} /代码>):


如果将最后一个方法从
First
更改为
FirstOrDefault
,则会生成
null
,因为
默认值(字符串)
null

我同意Xiaoy312。FirstOrDefault方法更好。然后检查它是否为空

public static string Test2(params string[] input)
{
     return input.FirstOrDefault(x => x == "apples")
}

那是不值得的。当我使用first或default时,我的“DefaultIfEmpty”被忽略,函数返回null。这对我来说很有意义,我没有考虑到操作顺序的重要性。。。我认为DefaultIfEmpty设置是一个默认设置,供以后的操作员在不返回任何内容的情况下使用。它的行为正如你所描述的。问题不是什么架构会更好。。。这个例子是人为的。问题是DefaultIfEmpty如何工作。亚库布的回答之所以获胜,是因为他指出了“秩序问题”,而我并不理解。
public static string Test1(params string[] input)
{
    return input
        .Where(x => x == "apples") // empty enumerable, because no item matches "apples"
        .DefaultIfEmpty("not found") // {"not found"}, since the enumerable is empty
        .First(); //"not found", since we have this item
} 

public static string Test2(params string[] input)
{
    return input
        .DefaultIfEmpty("not found") // { "oranges", "pears", "pineapples" }
                                     //i.e., nothing changes, because input is not empty
        .First(x => x == "apples"); //Exception because there is no
                                    //item that is equal to "apples"
}
public static string Test2(params string[] input)
{
     return input.FirstOrDefault(x => x == "apples")
}