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()))
我有一个 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()))