LINQ except() 的意外行为

Posted

技术标签:

【中文标题】LINQ except() 的意外行为【英文标题】:Unexpected behavior of LINQ Except() 【发布时间】:2021-03-10 02:55:02 【问题描述】:

我遇到了 LINQ 的一个奇怪的行为,除了我不明白的方法。我可以完全以不同的方式重写我的代码以使其正常工作,这不是我的问题。我只是想了解它为什么会失败:

public void MyMethod(MyClass whatever, params object[] values) // called with values = [ "mystr1", "mystr2", true, true ] 
  var valuesOfType = values.OfType<MyType>().ToList(); // valuesOfType is Empty List Count = 0
  values = values.Except(valuesOfType ).ToArray(); // values = [ "mystr1", "mystr2", true ] 

所以 values 的最后一个元素通过使用带有空列表的 except() 消失了!这怎么可能? 我再次在调试器中重新运行该行,它没有被中继到 2 个元素。自分配给values 不是问题,我用另一个变量尝试过,它仍然是trunkates。这里发生了什么?

PS: MyType 只是一个简单的类型,只有一个 get 属性。

虽然问题已经得到解答,但如果有人想亲自看看,这里有一个可复制的控制台应用程序:

namespace ConsoleApp1

    using System;
    using System.Linq;

    class Program
    
        static void Main(string[] args)
        
            var para = new object[] "str1", "str2", true, true;
            var temp = new TestClass(new Dummy1(), para);
        

        public class TestClass
        
            public TestClass(Dummy1 dummy1, params object[] values)
            
                var valuesOfType = values.OfType<Dummy2>().ToList();
                values = values.Except(valuesOfType).ToArray();

                foreach (var value in values)
                
                    Console.WriteLine(value);
                
                
                Console.ReadKey();
            
        

        public class Dummy1
        
        

        public class Dummy2
        
        
    

【问题讨论】:

【参考方案1】:

这是因为 LINQ Except 产生了 set 差异,因此删除了重复项。来自documentation:

这个方法首先返回那些没有出现在 第二。它不会在第二秒返回那些没有出现的元素 在第一。 只返回唯一元素。

在您的情况下,您有两个 true 值,因此只返回一个。

【讨论】:

这意味着list.Except(emptylist) 等于list.Distinct()? 基本上是的。它的实现首先创建一个包含来自第一个序列的元素的集合,然后排除来自第二个序列的元素(如果有)。如果没有 - 它只是从第一个序列创建一个集合 哇,谢谢!这完全解释了它。正如他们所说,阅读文档..

以上是关于LINQ except() 的意外行为的主要内容,如果未能解决你的问题,请参考以下文章

C# 两个集合比较差值 Linq的Except的用法

LINQ to SQL语句之Concat/Union/Intersect/Except

LINQ to SQL语句Concat/Union/Intersect/Except--2017年2月22日

LINQ 除了如何工作? [复制]

由于 .net-core 中的 linq-statement 导致 IEnumerable 和 List 之间出现意外差异? [复制]

WindowsLookAndFeel关于按钮着色的意外行为