我正在使用.net 2.0和c#,我已经在我的类中实现了IEquatible接口: -
public MyClass() : IEquatable<MyClass>
{
Guid m_id = Guid.NewGuid();
public Guid Id
{
get
{
return m_id;
}
}
#region IEquatable<MyClass> Members
public bool Equals(MyClass other)
{
if (this.Id == other.Id)
{
return true;
}
else
{
return false;
}
}
#endregion
}
这是不好的编程习惯吗?我已经读过我还需要实现Object.Equals和Object.GetHashCode,但我不知道为什么。
我希望能够检查MyClass的实例是否已包含在MyClass类型的通用列表中。为什么框架只建议你只实现Equals?
非常感谢任何帮助。
答案 0 :(得分:2)
您可以使用LINQ检查列表是否包含使用条件的自定义谓词的项目。在这种情况下,您无需覆盖Equals
,也无需实施IEquatable
:
// check if the list contains an item with a specific ID
bool found = someList.Any(item => item.ID == someId);
如果您需要将商品存储在Equals
或GetHashCode
中,则覆盖IEquatable
(使用Dictionary
)并实施Hashtable
非常有用。
答案 1 :(得分:0)
这是不好的编程习惯吗?
实施IEquatable<T>
非常棒,对结构来说更是如此,但仅仅做这么多还不够。
我读过我还需要实现Object.Equals
和Object.GetHashCode也是如此,但我不确定原因。
Read it here和here。说真的,这些已经讨论了很多次,而且非常简单..简而言之,你需要它来处理像Dictionary<,>
或HashSet<>
我希望能够检查MyClass的实例是否已包含在MyClass类型的通用列表中。为什么框架只建议你只实现Equals?
取决于收藏类型。对于List<T>
,它仅根据您定义Equals
方法的方式检查相等性,例如Contains
方法。对于大多数情况,您只需要Equals
。但是如果你有一个HashSet<T>
那么缺席和存在检查会利用你对象的哈希值。框架确实要求我们实现良好的哈希方法(不重新发明轮子)at appropriate places。
非常感谢任何帮助。
执行以下操作,但只有在对您有意义的情况下才必须重置运算符==
和!=
。看到你的课我认为你的班级有价值语义。否则只是忽略该部分(如果==
应该表示引用相等)...从你的guid获取hashcode就足够了,只要你需要测试相等性。
public sealed class MyClass : IEquatable<MyClass>
{
Guid m_id = Guid.NewGuid();
public Guid Id { get { return m_id; } }
public bool Equals(MyClass other)
{
if (ReferenceEquals(this, other))
return true;
if (ReferenceEquals(null, other))
return false;
return Id == other.Id;
}
public override bool Equals(object obj)
{
return Equals(obj as MyClass);
}
public static bool operator ==(MyClass lhs, MyClass rhs)
{
if (ReferenceEquals(lhs, null))
return ReferenceEquals(rhs, null);
return lhs.Equals(rhs);
}
public static bool operator !=(MyClass lhs, MyClass rhs)
{
return !(lhs == rhs);
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
为了避免错误,请使用可用的代码段here :为了更好地了解see this SO thread.