- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我知道我总是必须重写 Equals(object)
和 GetHashCode()
实现时 IEquatable<T>.Equals(T)
.
但是,我不明白,为什么在某些情况下 Equals(object)
胜过通用Equals(T)
.
例如,为什么会发生以下情况?如果我声明 IEquatable<T>
为接口(interface)实现具体类型 X
对于它,将军Equals(object)
被 Hashset<X>
调用在将这些类型的项目相互比较时。在所有其他情况下,至少有一侧被转换为界面,正确的 Equals(T)
被称为。
这里有一个代码示例来演示:
public interface IPerson : IEquatable<IPerson> { }
//Simple example implementation of Equals (returns always true)
class Person : IPerson
{
public bool Equals(IPerson other)
{
return true;
}
public override bool Equals(object obj)
{
return true;
}
public override int GetHashCode()
{
return 0;
}
}
private static void doEqualityCompares()
{
var t1 = new Person();
var hst = new HashSet<Person>();
var hsi = new HashSet<IPerson>();
hst.Add(t1);
hsi.Add(t1);
//Direct comparison
t1.Equals(t1); //IEquatable<T>.Equals(T)
hst.Contains(t1); //Equals(object) --> why? both sides inherit of IPerson...
hst.Contains((IPerson)t1); //IEquatable<T>.Equals(T)
hsi.Contains(t1); //IEquatable<T>.Equals(T)
hsi.Contains((IPerson)t1); //IEquatable<T>.Equals(T)
}
最佳答案
HashSet<T>
电话 EqualityComparer<T>.Default
在没有提供比较器时获取默认的相等比较器。
EqualityComparer<T>.Default
确定是否 T
工具 IEquatable<T>
.如果是,它使用那个,如果不是,它使用 object.Equals
和 object.GetHashCode
.
你的 Person
对象实现 IEquatable<IPerson>
不是IEquatable<Person>
.
当你有一个 HashSet<Person>
它最终检查是否 Person
是一个 IEquatable<Person>
,它不是,所以它使用 object
方法。
当你有一个 HashSet<IPerson>
它检查是否 IPerson
是一个 IEquatable<IPerson>
,确实如此,所以它使用了这些方法。
至于剩下的情况,为什么会这样:
hst.Contains((IPerson)t1);
调用 IEquatable
Equals
方法,即使它调用了 HashSet<Person>
.你在这里打电话 Contains
在 HashSet<Person>
上并传入 IPerson
. HashSet<Person>.Contains
要求参数为 Person
;一个IPerson
不是一个有效的论点。但是,HashSet<Person>
也是一个 IEnumerable<Person>
, 自 IEnumerable<T>
是协变的,这意味着它可以被视为 IEnumerable<IPerson>
, 它有一个 Contains
接受 IPerson
的扩展方法(通过 LINQ)作为参数。
IEnumerable.Contains
还使用 EqualityComparer<T>.Default
在未提供时获取其相等比较器。在这个方法调用的情况下,我们实际上调用了 Contains
在 IEnumerable<IPerson>
上, 这意味着 EqualityComparer<IPerson>.Default
正在检查是否 IPerson
是一个 IEquatable<IPerson>
,它是,所以 Equals
方法被调用。
关于c# - 为什么在 Hashset 或其他集合中使用继承对象时 Equals(object) 胜过 Equals(T)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28434991/
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 6 年前。 Improve t
无论我的数据点云的形状如何,我都希望收到具有相同坐标的方形图。 这是我的问题的原始说明。 xy <- data.frame(x = rnorm(100), y = r
我知道我总是必须重写 Equals(object)和 GetHashCode()实现时 IEquatable.Equals(T) . 但是,我不明白,为什么在某些情况下 Equals(object)胜
几个小时前我试图回答一个问题,我认为它揭示了 bash POSIX mode 中的一个有点模糊的错误。 .我匆忙地强烈告诉我事实并非如此。自相矛盾的答案明确表示这不是错误,因此被选为正确答案。 所以我
我是一名优秀的程序员,十分优秀!