相关疑难解决方法(0)

始终生成对象的哈希值

我正在尝试获取对象的哈希值(md5或sha).

我实现了这个:http: //alexmg.com/post/2009/04/16/Compute-any-hash-for-any-object-in-C.aspx

我正在使用nHibernate从数据库中检索我的POCO.
在此运行GetHash时,每次从数据库中选择并保湿时都会有所不同.我想这是预期的,因为底层代理会改变.

无论如何,

有没有办法在对象上获取所有属性的哈希值,每次都是一致的?

我已经玩弄了使用StringBuilder而不是this.GetType().GetProperties .....并在其上创建哈希,但这似乎效率低下的想法?

作为旁注,这是用于将这些实体从一个数据库(RDBMS)更改跟踪到NoSQL存储(比较哈希值以查看rdbms和nosql之间是否更改了对象)

.net c# hash

12
推荐指数
2
解决办法
3万
查看次数

为什么 Visual Studio 将“-1937169414”添加到生成的哈希码计算中?

如果您使用 Visual Studio 自己的重构菜单将 GetHashCode 实现添加到这样的类:

生成 GetHashCode 菜单

并选择类中唯一的 int 属性:

会员选择画面

它在 .NET Framework 上生成此代码:

public override int GetHashCode()
{
    return -1937169414 + Value.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)

(它HashCode.Combine(Value)在 .NET Core 上生成,我不确定它是否涉及相同的值)

这个值有什么特别之处?为什么不Value.GetHashCode()直接使用Visual Studio ?据我了解,它并没有真正影响哈希分布。由于它只是加法,连续的值仍然会累积在一起。

编辑:我只在不同的类中尝试过这个,Value但显然属性名称会影响生成的数字。例如,如果您将属性重命名为Halue,则数字变为 387336856。感谢 Gökhan Kurt 指出这一点。

c# visual-studio

12
推荐指数
1
解决办法
6322
查看次数

在C#中具有两个属性的对象上实现IEqualityComparer <T>

我有一个案例,我需要抓取一堆不同的项目,但我的源是一个具有两个属性的对象的集合,如下所示:

public class SkillRequirement
{
    public string Skill { get; set; }
    public string Requirement { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我尝试获得如下集合:

SkillRequirementComparer sCom = new SkillRequirementComparer();

var distinct_list = source.Distinct(sCom);
Run Code Online (Sandbox Code Playgroud)

我试图为此实现一个IEqualityComparer<T>,但我对这个GetHashCode()方法感到难过.

Comparer的类:

public class SkillRequirementComparer : IEqualityComparer<SkillRequirement>
{
    public bool Equals(SkillRequirement x, SkillRequirement y)
    {
        if (x.Skill.Equals(y.Skill) && x.Requirement.Equals(y.Requirement))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public int GetHashCode(SkillRequirement obj)
    {
        //?????
    }
}
Run Code Online (Sandbox Code Playgroud)

通常我会GetHashCode()在一个属性上使用,但因为我在两个属性上进行比较,所以我有点不知所措.我做错了什么,或者遗漏了一些非常明显的东西?

c# linq distinct iequalitycomparer

11
推荐指数
1
解决办法
6129
查看次数

是否应该在引用类型上覆盖Equals始终意味着值相等?

如果没有为引用类型做任何特殊操作,则Equals()意味着引用相等(即相同的对象).如果我选择覆盖Equals()引用类型,它是否总是意味着两个对象的值是等价的?

考虑这个可变性 Person类:

class Person
{
    readonly int Id;

    string FirstName { get; set; }
    string LastName { get; set; }
    string Address { get; set; }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

表示完全相同的人的两个对象将始终具有相同的Id,但是其他字段可能随时间不同(即,在地址改变之前/之后).

对于这个对象,Equals可以定义为不同的东西:

  • 价值平等:所有字段都相等(代表同一个人但具有不同地址的两个对象将返回false)
  • 身份平等:Ids相等(代表同一个人但具有不同地址的两个对象将返回true)
  • 参考平等:即不实施等于.

问题:这个课程中哪些(如果有的话)更适合?(或许问题应该是,"这个班级的大多数客户如何期望Equals()表现?")

笔记:

  • 使用Value Equality使得在Hashsetor中使用这个类更加困难Dictionary
  • 使用Identity Equality使得Equals和=运算符之间的关系变得奇怪(即在检查两个Person对象(p1和p2)之后返回true)Equals(),您可能仍然希望更新引用以指向"较新的"Person对象,因为它是不等值).例如,以下代码读取奇怪 - 似乎它什么都不做,但它实际上是删除p1并添加p2:

    HashSet<Person> people = new HashSet<Person>();
    people.Add(p1);
    // ... p2 is an new object that has the same Id as p1 …
    Run Code Online (Sandbox Code Playgroud)

.net c#

11
推荐指数
2
解决办法
1348
查看次数

实现GetHashCode

可能重复:
重写的System.Object.GetHashCode的最佳算法是什么?

什么构成了GetHashCode方法的良好实现?我做了一些谷歌搜索,并找到了一些好线(MSDN),但似乎逻辑只是操纵存储为类中的字段的两个数字.这个方法实际逻辑是否这么简单?

c#

10
推荐指数
1
解决办法
1万
查看次数

自定义类型GetHashCode

可能重复:
重写的System.Object.GetHashCode的最佳算法是什么?

我需要覆盖由三个字符串组成的类型的GetHashCode方法.这是我的代码:

protected override int GetHashCode()
{
    return str1.GetHashCode() + str2.GetHashCode() + str3.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)

这种方法实现的安全方法是什么?

.net c#

10
推荐指数
1
解决办法
7733
查看次数

C# - 类的通用HashCode实现

我正在研究如何为类构建最好的HashCode,我看到了一些算法.我看到了这一个:Hash Code实现,似乎是.NET类HashCode方法类似(通过反映代码看).

所以问题是,为什么不创建上面的静态类以便自动构建HashCode,只需传递我们认为是"键"的字段.

// Old version, see edit
public static class HashCodeBuilder
{
    public static int Hash(params object[] keys)
    {
        if (object.ReferenceEquals(keys, null))
        {
            return 0;
        }

        int num = 42;

        checked
        {
            for (int i = 0, length = keys.Length; i < length; i++)
            {
                num += 37;
                if (object.ReferenceEquals(keys[i], null))
                { }
                else if (keys[i].GetType().IsArray)
                {
                    foreach (var item in (IEnumerable)keys[i])
                    {
                        num += Hash(item);
                    }
                }
                else
                {
                    num += keys[i].GetHashCode();
                }
            }
        }

        return …
Run Code Online (Sandbox Code Playgroud)

c# hashcode

10
推荐指数
1
解决办法
8969
查看次数

为什么使用GetHashCode()而不是Equals()?

HashSet<T>.Add首先比较结果GetHashCode.如果它们是相同的,它会调用Equals.

现在,我的理解是为了实现GetHashCode,必须用对象的字段来完成某些事情.一个简单的示例实现可以在被覆盖的System.Object.GetHashCode的最佳算法是什么?.

在我的测试中,在填充随机数据的1.000.000对对象上进行比较,两者之间的性能或多或少相等.GetHashCode在链接示例中实现,Equals只需调用Equals所有字段.那么为什么要用GetHashCodeEquals

.net performance equals gethashcode

10
推荐指数
2
解决办法
2105
查看次数

在C#中创建GetHashCode方法

在C#中为类创建自己的GetHashCode方法的最佳方法是什么?假设我有一个简单的类(它覆盖了Equals方法),如下所示:

class Test
{
   public string[] names;

   public double[] values;

   public override bool Equals(object obj)
   {
      return (obj is Test) && this.Equals((Test)obj);
   }

   public bool Equals(Test t)
   {
      return names.Equals(t.names) && values.Equals(t.values);
   }
}
Run Code Online (Sandbox Code Playgroud)

我应该使用GetHashCode方法的默认代码吗?

public override int GetHashCode()
{
   return base.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)

我应该将该方法基于我班级的内容吗?

public override int GetHashCode()
{
   return names.GetHashCode() + values.GetHashCode() ;
}
Run Code Online (Sandbox Code Playgroud)

或者我应该做些什么?

.net c# hashcode gethashcode

9
推荐指数
1
解决办法
1万
查看次数

为什么xor运算符用于计算哈希码?

在这篇MSDN文章 http://msdn.microsoft.com/en-us/library/ms132123.aspx中, 它讨论了Class Equalitycomparer并有一个例子.在这个关于比较它的例子中它有这个类 -

class BoxSameDimensions : EqualityComparer<Box>
{
    public override bool Equals(Box b1, Box b2)
    {
        if (b1.Height == b2.Height & b1.Length == b2.Length
            & b1.Width == b2.Width)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public override int GetHashCode(Box bx)
    {
        int hCode = bx.Height ^ bx.Length ^ bx.Width;
        return hCode.GetHashCode();
    }
}
Run Code Online (Sandbox Code Playgroud)

我不明白行hCode = bx.Height ^ bx.Length ^ bx.Width;

有人可以解释一下吗?为什么xor?

.net c#

9
推荐指数
1
解决办法
3531
查看次数