Zac*_*son 25 .net c# entity-framework
我重写了我班级的Equals()来比较Guid类型的ID值.
然后Visual Studio警告:
...重写Object.Equals(object o)但不覆盖Object.GetHashCode()
所以我然后也像这样覆盖它的GetHashCode():
public partial class SomeClass
{
public override bool Equals(Object obj)
{
//Check for null and compare run-time types.
if (obj == null || this.GetType() != obj.GetType()) return false;
return this.Id == ((SomeClass)obj).Id;
}
public override int GetHashCode()
{
return this.Id.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
它似乎工作.我做得对吗?记住Id是Guid类型.我的类是实体框架对象是否重要?
Eri*_*ert 33
正如其他人所说的那样,在平等中使用反思似乎很狡猾.抛开这一点,让我们专注于GetHashCode.
您必须不违反GetHashCode的主要规则是,如果两个对象相等,则它们必须具有相同的哈希码.或者,相同的说法是,如果两个对象具有不同的哈希码,那么它们必须是不相等的. 你的实现看起来不错.
你可以自由地违反反过来.也就是说,如果两个对象具有相同的哈希码,则允许它们相等或不相等,如您所见.
我假设"Id"是一个不可变的属性.如果"Id"可以在对象的生命周期内更改,那么将对象放入哈希表时可能会出现问题.考虑确保在计算相等性和哈希码时仅使用不可变属性.
您的实现看起来不错,但您提出问题的事实表明您可能无法掌握构建GetHashCode实现的所有细微因素.一个好的开始是我关于这个主题的文章:
http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/
它对我来说是正确的.每当我做这样的事情时,我通常也会实现,IEquatable以便在相同编译时类型的变量之间进行比较会更有效.
public partial class SomeClass : IEquatable<SomeClass>
{
public override bool Equals(Object obj)
{
return Equals(obj as SomeClass);
}
public bool Equals(SomeClass obj)
{
if (obj == null)
return false;
return Id == obj.Id;
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
此结构还允许具有相同Id的更多派生对象进行比较,使其等于较少派生的对象.如果这不是所需的行为,那么您还必须像在问题中那样比较类型.
if (obj.GetType() != typeof(SomeClass)) return false;
Run Code Online (Sandbox Code Playgroud)
既然你没有处理密封类,我建议不要像这样检查类的相等性this.GetType() != obj.GetType().任何子类都SomeClass应该能够参与Equals,所以你可能想要使用它:
if (obj as SomeClass == null) return false;
Run Code Online (Sandbox Code Playgroud)
传统Equals上以这样的方式实现,即如果两个对象在各方面完全相同,则它们将只是"等于".例如,如果有两个对象表示数据库中的同一对象,但是其中一个对象具有与另一个不同的Name属性,则对象不会被视为"等于",并且应尽可能避免生成相同的"Hashcode".
最好是在"不平等"方面犯错,而不是冒险调用两个不相等的对象.这就是对象的默认实现使用对象本身的内存位置的原因:除非它们是完全相同的对象,否则不会将两个对象视为"相等".所以我要说除非你想要写两个GetHashCode并且Equals以这样的方式检查它们所有属性的相等性,否则最好不要覆盖任何一种方法.
如果您有一个数据结构(如a HashSet),您特别希望根据ID值确定相等性,则可以IEqualityComparer为该数据结构提供特定的实现.
你得到了第一个问题的优秀答案:
我做得对吗?
我会回答你的第二个问题
我的类是实体框架对象是否重要?
是的,这很重要.实体框架HashSet在内部使用了很多.例如,动态代理HashSet用于表示集合导航属性和EntityObject使用EntityCollection,而后者又在HashSet内部使用.
| 归档时间: |
|
| 查看次数: |
20985 次 |
| 最近记录: |