System.Collections.Immutable类型:为什么没有.Equals

时间:2016-03-12 19:08:46

标签: c# .net immutability

ByteBuffer byteBuffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[byteBuffer.remaining()]; 
byteBuffer.get(bytes); 
FileOutputStream fileOutputStream = null; 
try {  
     fileOutputStream = new FileOutputStream(mImageFile);    
     fileOutputStream.write(bytes); 
} 
catch (FileNotFoundException e) {  
   // TODO Auto-generated catch block  e.printStackTrace(); } catch    
   (IOException e) {  
          // TODO Auto-generated catch block  e.printStackTrace(); 
   } 
finally {  
    mImage.close();  
    try {   
       fileOutputStream.close();  
    } 
    catch (IOException e) {   // TODO Auto-generated catch block  
        e.printStackTrace();  
    } 
} 

var a = ImmutableList<int>.Empty.Add(1).Add(2).Add(3); var b = ImmutableList<int>.Empty.Add(1).Add(2).Add(3); Console.WriteLine(a.Equals(b)); // False 来电a.Equals(b)上方的代码中,因为Object.Equals不会覆盖ImmutableList<T>,而Equals(object)是引用类型{ {1}}做(无用的)参考比较。

问题:为什么不ImmutableList<T>覆盖Object.Equals?这将是直截了当的,并期望将每个包含的对象与ImmutableList<T>进行比较,并根据这些比较返回结果。测试框架的其余部分甚至是一致的(参见.Equals

注意:上面的代码是使用.Equals

进行测试的

3 个答案:

答案 0 :(得分:3)

您要做的是测试集合的内容是否相等。没有.NET集合覆盖Equals来执行此操作。相反,请使用SequenceEqual

Console.WriteLine(a.SequenceEqual(b));

关于为什么 - 这是一个意见问题,我想。大多数面向参考的平台都尽力避免将引用相等性与内容相等混淆。

String实际上是非常特殊的情况,虽然它确实实现了IEnumerable,但在List /等意义上,通常不会将其视为适当的容器。是

答案 1 :(得分:0)

没有任何收藏品。他们都继承Object.Equals(Object)并且不会覆盖它。使用Enumerable.SequenceEqual方法比较两个集合的元素。

答案 2 :(得分:0)

您“可以”创建一个包装类并覆盖 Equality 和 HashCode 方法...这可能对 c# 记录很有帮助,这样您就不必继续覆盖自动生成的方法。

    public sealed class ImmutableListSequence<T>
    {
        public ImmutableListSequence(ImmutableList<T> items)
        {
            Items = items;
        }

        public ImmutableList<T> Items { get; }

        public override int GetHashCode()
        {
            unchecked
            {
                return Items.Aggregate(0, (agg, curr) => (agg * 397) ^ (curr != null ? curr.GetHashCode() : 0));
            }
        }

        public override bool Equals(object? obj)
        {
            if (obj is ImmutableListSequence<T> second)
            {
                return Items.SequenceEqual(second.Items);
            }

            return false;
        }
    }