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