C#List <object>。等于对象比较失败

时间:2018-10-08 11:57:43

标签: c# .net list object equals-operator

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

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#的新手,因此我搜索了各种解决方案,包括.ContainsEqual(在上面的Equal中添加了覆盖)。我也了解,只需使用where like this就可以实现比较。但是,随着我可能在类中添加了更多元素,如果可能的话,我想坚持使用等于或包含。我用来比较然后如果不存在插入的代码如下所示:

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()
                }
                );
        }

但是它忽略了条件并再次添加了相同的语言。从所附图片中可以看到。enter image description here

请问我该如何解决?

2 个答案:

答案 0 :(得分:4)

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

正确实施IEquatable<T>override Equals(object) and GetHashCode()。来自What does Collection.Contains() use to check for existing objects?

  

要么在您的自定义类上实现IEquatable,要么覆盖Equals(和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()的正确实现。

答案 1 :(得分:0)

您应该使用Contains()方法。另外,您应该为IEquatable实现MultiLingualColumn接口或实现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()))