【问题标题】:Using || operator in LinQ使用 || LinQ 中的运算符
【发布时间】:2016-03-17 15:25:21
【问题描述】:

我有一个小例子可以使用 || Where() 的运算符,但可能有问题:

var list = new List<string>
{
   "One",
   "Two",
   "Three"
};

string s = "One";
var numbers = list.Where(x => x == s || !string.IsNullOrEmpty(x));

foreach(var number in numbers)
{
   Console.WriteLine(number);

   // output:
   // One
   // Two
   // Three
}

s = null;    
numbers = list.Where(x => x == s || !string.IsNullOrEmpty(x));

foreach(var number in numbers)
{
   Console.WriteLine(number);

   // output:
   // One
   // Two
   // Three
}

在第一种情况下,为什么 !string.IsNullOrEmpty(x) 在我们有 x == s 为真时仍然检查?

我明白了:

if (A && B)
{
   // we need A and B are true
}

if (A || B)
{
   // we need A is true or B is true
   // if A is true, no ned to check B is true or not
}

所以,我的问题是:我误会了什么?

【问题讨论】:

  • 因为它会评估列表中每个元素的查询。
  • 嗯,这个问题是根据记录提出的。所以"Two" => "Two" == "One" || !string.IsNullOrEmpty("Two")
  • !String.IsNullOrEmpty(x) 对于列表中的每个字符串始终为 true。您的 LINQ 是“当字符串等于 One 或字符串不为空且不为空时包含”
  • 为什么你会认为第一个列表项是根据你的 Where 子句的后半部分检查的?它似乎按预期工作:第一项通过,因为它等于 s,其他通过 Where 检查的第二部分,因为它们不为空。
  • 为什么投反对票?这是一个完全有效的问题,带有很好的示例代码。 OP 不了解 Where 方法的工作原理这一事实并不值得反对。

标签: c# linq logical-operators


【解决方案1】:

你说得对:

a || b

如果atrue,则不会评估b,但是:

Where LINQ 使用 Lambda 表达式检查 Enumerable 中的 每个 元素,无论之前的结果如何。因此,当你这样做时:

string s = "One";
var numbers = list.Where(x => x == s || !string.IsNullOrEmpty(x));

只要Where lambda 表达式有效,它就会检查查询中的每个元素:

x == s || !string.IsNullOrEmpty(x)); //x = "One", x == s is true
x == s || !string.IsNullOrEmpty(x)); //x = "Two", !string.IsNullOrEmpty(x) is true
x == s || !string.IsNullOrEmpty(x)); //x = "Three", !string.IsNullOrEmpty(x) is true

这样你就得到了所有的元素。

如果您想在不再满足条件后立即停止获取查询结果,请考虑使用TakeWhile

【讨论】:

    【解决方案2】:

    var numbers = list.Where(x =&gt; x == s || !string.IsNullOrEmpty(x)); 从列表中获取每个元素 - x 并检查它是否符合特定条件。

    条件为x == s!string.IsNullOrEmpty(x),因此元素应至少符合条件的一部分。

    特别是,列表的每个元素都满足!string.IsNullOrEmpty(x) 条件。

    尝试将null 添加到您的列表中。它不符合!string.IsNullOrEmpty(x),也不符合x == s,因此不会包含在结果中。

     var list = new List<string>
     {
            "One",
            "Two",
            "Three",
            null
     };
    
    var numbers = list.Where(x => x == "One" || !string.IsNullOrEmpty(x)).ToList();
    

    【讨论】:

      【解决方案3】:

      运营商是正确的。在您的第一个示例中:

      string s = "One";
      var numbers = list.Where(x => x == s || !string.IsNullOrEmpty(x));
      
      foreach(var number in numbers)
      {
         Console.WriteLine(number);
      
         // output:
         // One <-- First condition is met
         // Two <-- First condition is not met so goes into the OR operator and returns true
         // Three <--Same as above
      }
      

      https://msdn.microsoft.com/en-us/library/6373h346.aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-20
        • 1970-01-01
        • 2011-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多