C# List<Object>.Equals 对象比较失败

C# List<Object>.Equals fails on object comparison

我有一个 class 如下。对于此 class 的对象,我需要添加一种新语言以防它不存在

using System;
using System.Collections.Generic;
namespace discovery.POCO
{
    public class MultiLingualObject 
    {
        public string TableName { get; set; }
        public string BranchId { get; set; }
        public int    GenericId { get; set; }
        public string GenericCode { get; set; }
        public List<MultiLingualColumn> MultiLingColumnsCollection = new List<MultiLingualColumn>();
    }
    public class MultiLingualColumn : IEquatable<MultiLingualColumn>
    {
        public string ColumnName { get; set; }
        public string LanguageCode { get; set; }
        public string LanguageText { get; set; }

        public bool Equals(MultiLingualColumn other)
        {
            if (other == null) return false;
            return  string.Equals(ColumnName,other.ColumnName) &&
                    string.Equals(LanguageCode, other.LanguageCode) &&
                    string.Equals(LanguageText, other.LanguageText);
        }
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != GetType()) return false;
            return Equals(obj as MultiLingualColumn);
        }
    }

}

由于我是 C# 的新手,我搜索了各种解决方案,包括 .Contains or Equal (from where I have added override to my Equal above). I also understand I can achieve the comparison by simply using where like this。然而,由于我可能有更多元素添加到 class,如果可能的话,我想坚持使用 Equal 或 Contains。我用来比较然后在不存在时插入的代码如下

internal void UpdateLocalMultiLing()
        {
            POCO.MultiLingualColumn _equals = new POCO.MultiLingualColumn()
            {
                ColumnName = InvoiceComment.Name.TrimEnd(),
                LanguageCode = inputLanguage,
                LanguageText = InvoiceComment.Value.TrimEnd()
            };

            if (!SupplierMultiLing.MultiLingColumnsCollection.Equals(_equals))
                SupplierMultiLing.MultiLingColumnsCollection.Add(new POCO.MultiLingualColumn
                {
                    ColumnName   = InvoiceComment.Name.Trim(),
                    LanguageCode = inputLanguage,
                    LanguageText = InvoiceComment.Value.Trim()
                }
                );
        }

但它忽略了条件并再次添加相同的语言。从附图中可以看出。

有人能告诉我应该修复什么吗?

您正在将列表与单个对象进行比较。您需要 .Contains() 而不是 .Equals()

要么正确实施 IEquatable<T>,要么 override Equals(object) and GetHashCode(). From What does Collection.Contains() use to check for existing objects?

either implement IEquatable on your custom class, or override the Equals (and GetHashCode)

此代码打印 "True":

public class Foo : IEquatable<Foo>
{
    public string Bar { get; set; }

    public bool Equals(Foo other)
    {
        return other.Bar == this.Bar;
    }
}

public static void Main()
{
    var list = new List<Foo>
    {
        new Foo { Bar = "Baz" }
    };

    Console.WriteLine(list.Contains(new Foo { Bar = "Baz" }));
}

但是正如@Jeppe 正确评论的那样,建议还为其他集合和比较类型提供 GetHashCode() 的正确实现。

你应该使用Contains()方法。您还应该为 MultiLingualColumn 实现 IEquatable 接口或实现 IEqualityComparer 并将第二个参数传递给 Contains()。我更喜欢第二个选项:

public class MultiLingualColumnComparer : IEqualityComparer<MultiLingualColumn>
{
    public bool Equals(MultiLingualColumn x, MultiLingualColumn y)
    {
        //...
    }

    public int GetHashCode(MultiLingualColumn obj)
    {
        //...
    }
}

然后:

if (!SupplierMultiLing.MultiLingColumnsCollection.Contains(_equals, new MultiLingualColumnComparer()))