Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 重写GetHashCode_C#_Algorithm_Methods_Overriding_Gethashcode - Fatal编程技术网

C# 重写GetHashCode

C# 重写GetHashCode,c#,algorithm,methods,overriding,gethashcode,C#,Algorithm,Methods,Overriding,Gethashcode,如您所知,GetHashCode返回一个半唯一的值,可用于标识集合中的对象实例。作为一种良好的实践,建议重写此方法并实现自己的方法 我的问题是-在处理自定义对象时是否覆盖此方法?如果是,您使用什么算法来生成唯一ID 我正在考虑生成一个GUID,然后从标识符获取整数数据。通常我使用类的组件属性中的聚合GetHashCode。例如 public class Test { public string Text { get; set; } public int Age { get; set; }

如您所知,GetHashCode返回一个半唯一的值,可用于标识集合中的对象实例。作为一种良好的实践,建议重写此方法并实现自己的方法

我的问题是-在处理自定义对象时是否覆盖此方法?如果是,您使用什么算法来生成唯一ID


我正在考虑生成一个GUID,然后从标识符获取整数数据。

通常我使用类的组件属性中的聚合GetHashCode。例如

public class Test
{
  public string Text { get; set; }
  public int Age { get; set; }

  public override GetHashCode()
  {
    int result = 
      string.IsNullOrEmpty(Text) ? 0 : Text.GetHashCode()
      + Age.GetHashCode();

    return result;
  }
}

在我个人的使用中,我只在重写equals方法时才重写。通常,我会对我知道可能会对其运行LINQ to objects查询或其他比较操作的对象执行此操作

我通常返回主键值,比如LINQ to SQL实体或DTO对象。无论返回什么,如果不在本地存储值,可能会产生意外结果


HTH.

如果要覆盖Equals,则只需覆盖GetHashCode。默认的GetHashCode由运行时以您想要的方式实现——每个对象都有一个由运行时指定的隐藏字段


实际上,IDE应该为您做这件事——当您键入“override GetHashCode”时,IDE应该生成这个样板代码。Visual Studio不这样做,但会这样做。

我通常会覆盖数据类(即值语义有意义的类)的哈希代码和相等性检查方法。请看一个常见实现的问题。如果您重写hashcode,则重写等于。使用GUID是一个非常糟糕的想法,因为您希望两个不同实例但具有相同值的对象具有相同的hashcode,并且for equals返回true。

当您重写
GetHashCode()
时,您还需要重写
equals()
操作符==
操作符=。并且要非常小心地满足这些方法的所有要求

指导方针是。最重要的一句话:

在可变类型中重写运算符==不是一个好主意


如果使用resharper,它可以为您生成GetHashCode()、Equals和运算符方法体

按Alt+Insert可访问此菜单


请阅读及其答案。它概述了一个好的哈希代码实现。对于易变对象的overiding
GetHashCode
也有很好的讨论。我不知道“半唯一”是什么意思。。。值是唯一的或不是唯一的,哈希代码不是唯一的。因此,它不允许您在列表中标识对象。覆盖
GetHashCode
不是一种“好的做法”,这是您在需要时所做的事情(例如,将对象用作字典中的键),并不是因为你认为这是一个好的做法。使用对象作为键可以被视为识别集合中的对象——这正是我寻找关于构建标识符的最佳算法的输入的原因。对于半唯一ID:Dennis,您首先需要考虑您想要什么样的平等行为。对于默认的引用等式(对于具有标识的可变对象),您完全不需要执行任何操作。这不是一种很好的方法,请参见“一般情况下添加不利于创建复合哈希代码”。但在这个具体的例子中,我看不出有什么问题。当然,不重写Equals而重写GetHashCode没有多大意义。好吧,你每天都能学到一些东西!GetHashCode方法的默认实现不保证不同对象的唯一返回值。因此,此方法的默认实现不得用作哈希目的的唯一对象标识符。From:在VS中,必须使用
等于
代码段instead@brain-我读过这个。这是否意味着,当您想在字典中存储对象时,应该始终覆盖GetHashCode?我不这么认为——几乎没有人这样做。出于字典的目的,默认实现可以正常工作。它不是完美的,但很好:据我所知,这毫无意义,因为对象不会改变它的状态。什么是没有意义的?字符串是不可变的,您是否从未使用过
name==“x”
?是的,但是当您修改字符串时,您创建了一个新对象(例如,当您使用Replace时)。关键是,在重新分配变量之前,依赖==保持为真是很自然的;让突变副作用改变==的过去含义是不直观的,因为默认情况下支持比较运算符的任何东西都是值类型或不可变的。只有当您说var=“new value”时,这些值才会改变,这明确意味着前面的==可能不再为真。引用类型可以改变其他代码的状态,而方法在其他地方改变对象可能会改变相等性。Equals不提供相同的期望值,因为它是一个方法定义,而不是语法。