C# List<Object>.Equals не удается при сравнении объектов

У меня есть класс, как показано ниже. К объекту этого класса мне нужно добавить новый язык, если он не существует

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 или Equal (откуда я добавил переопределение к моему Equal выше). Я также понимаю, что могу добиться сравнения, просто используя где это. Тем не менее, так как я мог бы добавить больше элементов в класс, я хотел бы придерживаться либо 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()
                }
                );
        }

все же он игнорирует условие и снова добавляет тот же язык. Это видно из прикрепленного изображения.

Можно ли посоветовать, что мне исправить, пожалуйста?

2 ответа

Решение

Вы сравниваете список с одним объектом. Тебе нужно .Contains() вместо .Equals(),

Либо правильно реализовать IEquatable<T> или переопределить Equals(object) а также GetHashCode(), Из чего Collection.Contains() использует для проверки существующих объектов?:

либо реализуйте 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() для других типов сбора и сравнения.

Вы должны использовать 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()))
Другие вопросы по тегам