我一定要重写GetHash code和等于新的类?重写、GetHash、于新、code

2023-09-03 04:11:59 作者:谢绝虚假

好了,所以如果我重载Equals,我需要重写GetHash code,反之亦然。

Okay, so if I override Equals, I need to override GetHashCode and vice versa.

但我只是想:我应该始终覆盖这两个中的任何一类?特别是,如果我知道,我会用他们的字典或类似的藏品?虽然这是fairly直线前进,它仍然是每一个类的额外的工作。

But I just wonder: Should I always override these two in any class? Especially if I know that I will use them in a Dictionary or similar collections? While this is fairly straight forward, it's still an extra work for every class.

是System.Object的实施已经够糟糕担心这一点?

Is the System.Object implementation bad enough to worry about this?

编辑:你能否详细一点什么是价值和借鉴的平等?所以,如果我有两个字符串(S1和S2)是两个测试,他们是平等的价值,但由于它们是两个不同的字符串,它们不是参考平等吗?好吧,对于字符串这是一个没有脑子,但什么是常见的情况,您都需要引用或值相等?

Can you detail a bit more what is Value and Reference equality? So if I have two strings (s1 and s2) that are both "test", they are value equal, but since they are two different strings, they are not reference-equal? Ok, for strings it's a no-brainer, but what are the common situations where you would want Reference or Value Equality?

推荐答案

据我所知,你只需要,如果你需要的值相等语义覆盖它们。该System.Object的实现并不坏,它只是只能执行基准检查(这是在该级别所有的实现可以做到)。

As far as I'm aware you only need to override them if you need value equality semantics. The System.Object implementation isn't 'bad', it just only does a reference check (which is all an implementation at that level can do).

总之:如果你需要某种形式的基于价值的平等(基于类的属性平等),然后是,重写了。否则,它应该超过细已经

In short: If you need some sort of value based equality (equality based on properties of the class), then yes, override away. Otherwise, it should be more than fine already.

编辑: 你只需要对其进行覆盖在上面的情况。如果您覆盖一个,你就需要重写既为明显的原因(他们需要的是一致的,等等)。您的可以的覆盖对每一类在其他的答案中标注的其他原因(如性能,在所有使用哈希值的算法,即词典键,等等),但你并不需要,默认 System.Object的的实施将正常工作。

You only need to override them in the case above. If you override one, you do need to override both for the obvious reasons (they need to be consistent, etc). You can override them on every class for other reasons noted in other answers (like performance in algorithms that use the hash value, ie. Dictionary keys, etc), but you don't need to, the default System.Object implementation will work correctly.

编辑2: 更多信息请,所以这里去。请看下面的伪类:

EDIT 2: More information requested, so here goes. Consider the following pseudo-class:

public class User {
    private int _id;
    private string _username;
    public string Username { get {return _username;}};
    // [snip] Whatever other properties we might like to have.

    public User(string username) {
        // Initialise our user from a database, or whatever.
    }
}

既然这样,下面的code,似乎直观的:

As it stands, the following code, might seem intuitive:

User foo = new User("me");
User bar = new User("me");
User baz = foo;

if (foo.Equals(bar)) {
    Console.WriteLine("1: Success!");
}
if (foo.Equals(baz)) {
    Console.WriteLine("2: Success!");
}

但它只会打印出来:

But it will only print out:

2:成功

为什么呢? 是类的两个单独的实例,并有单独的参考。参考就像C / C ++的指针。 foo和巴兹是相同的参考,因为一个从其他分配。它们都具有相同的值的,虽然,用户名为我。基于价值的样本实施 .Equals 的实施可能是:

Why? foo and bar are two seperate instances of the class, and have separate references. A reference is like a pointer in C/C++. foo and baz are the same reference because one was assigned from the other. They all have the same value though, the user called "me". A sample implementation of a value based .Equals implementation might be:

partial class User {
    public override bool Equals(object b) {
        if (b == null) return false;
        if (b.GetType() != this.GetType()) return false;

        // Now the heavy lifting
        User other = (User)b;
        if (other._id == this._id) return true;
        else return false;
    }
}

请参阅如何检查对于阶级属性的一部分,以确定相等?这是在工作中的值相等。参考平等的将只是一个简单的此== b 检查。

See how it checks against part of the class's properties to determine equality? That's value equality at work. Reference equality would just be a simple this == b check.

 
精彩推荐
图片推荐