C# 在实施IEqualityComparer时<;T>;。GetHashCode(T obj),我可以使用当前实例吗';s状态,还是必须使用obj?
为什么在我实现IEqualityComparer时,它有一个GetHashCode(T obj)参数?当然,它不是一个静态对象,所以为什么我不能使用当前实例的状态来生成哈希代码呢?C# 在实施IEqualityComparer时<;T>;。GetHashCode(T obj),我可以使用当前实例吗';s状态,还是必须使用obj?,c#,interface,polymorphism,C#,Interface,Polymorphism,为什么在我实现IEqualityComparer时,它有一个GetHashCode(T obj)参数?当然,它不是一个静态对象,所以为什么我不能使用当前实例的状态来生成哈希代码呢?this==obj 我很好奇,因为我正试图这样做: public abstract class BaseClass : IEqualityComparer<BaseClass> { public abstract int GetHashCode(BaseClass obj); } public c
this==obj
我很好奇,因为我正试图这样做:
public abstract class BaseClass : IEqualityComparer<BaseClass>
{
public abstract int GetHashCode(BaseClass obj);
}
public class DerivedClass : BaseClass
{
public int MyData;
public override int GetHashCode(BaseClass obj)
{
return MyData.GetHashCode();
// Or do I have to do this:
// return (DerivedClass)obj.MyData.GetHashCode();
}
}
公共抽象类基类:IEqualityComparer
{
公共抽象int GetHashCode(基类obj);
}
公共类派生类:基类
{
公共数据;
公共覆盖int GetHashCode(基类obj)
{
返回MyData.GetHashCode();
//或者我必须这样做:
//return(DerivedClass)obj.MyData.GetHashCode();
}
}
我试图阻止执行强制转换,因为它被用在真正高性能的代码中。如果您没有使用传入的
obj
参数中的信息,您的哈希代码将不会因不同的传入对象而变化,也不会有用。比较器不是要获取哈希代码或进行比较的对象的实例
事实上,您可以在GetHashCode
中使用comaprer的本地字段,甚至可以将MyData
作为哈希代码返回,如示例所示-它仍然满足GetHashCode
要求“为同一对象返回相同的值数据”。但在您的示例中,比较器的所有哈希代码都是相同的,因此将其用于字典将本质上把字典变成列表
这同样适用于Equals
调用-实际上,您可以始终返回true
,但它有多有用?如果您不使用传入的obj
参数中的信息,则哈希代码不会因不同的传入对象而变化,也不会有用。比较器不是要获取哈希代码或进行比较的对象的实例
事实上,您可以在GetHashCode
中使用comaprer的本地字段,甚至可以将MyData
作为哈希代码返回,如示例所示-它仍然满足GetHashCode
要求“为同一对象返回相同的值数据”。但在您的示例中,比较器的所有哈希代码都是相同的,因此将其用于字典将本质上把字典变成列表
这同样适用于Equals
调用-实际上,您可以随时返回true
,但它会有多大用处?我认为这里的主要问题是您对它感到困惑
IEquatable
定义一种方法,用于确定当前实例(this
)是否等于相同类型的实例。换句话说,它用于测试objA.Equals(objB)
。在实现此接口时,建议您也重写GetHashCode()
instance方法
IEqualityComparer
定义了用于测试给定类型的两个对象是否相等的方法,换句话说,它用于测试comparer.Equals(objA,objB)
。因此有必要提供一个对象作为GetHashCode
的参数(记住,它不同于它从对象继承的GetHashCode
)
你可以把IEquatable
想象成你的对象的表达方式,“这就是我如何知道我是否与其他事物相等的方式”,而IEqualityComparer
想象成你的对象的表达方式,“这就是我如何知道其他两个事物是否相等的方式”
有关如何在框架中使用这两个接口的一些好例子,请参见:
- 它实现了
IEquatable
- 它实现了
IEqualityComparer
您是否应该使用IEqualityComparer
的当前状态来确定哈希代码?如果状态是可变的,那么否使用哈希的任何地方(例如哈希集
或字典
)都将缓存哈希代码并用于高效查找。如果由于比较器的状态发生变化而导致哈希代码发生变化,那么将完全破坏存储哈希的数据结构的有用性。现在,如果状态是不可变的(即,它仅在创建比较器时设置,并且不能在比较器的整个生命周期内进行修改),那么可以,但我仍然建议您不要这样做,除非您有很好的理由
最后,您提到了性能。老实说,这听起来像。我建议不要太担心性能,直到您确定这一行代码导致了问题 我认为这里的主要问题是你把它弄糊涂了
IEquatable
定义一种方法,用于确定当前实例(this
)是否等于相同类型的实例。换句话说,它用于测试objA.Equals(objB)
。在实现此接口时,建议您也重写GetHashCode()
instance方法
IEqualityComparer
定义了用于测试给定类型的两个对象是否相等的方法,换句话说,它用于测试comparer.Equals(objA,objB)
。因此有必要提供一个对象作为GetHashCode
的参数(记住,它不同于它从对象继承的GetHashCode
)
你可以把IEquatable
想象成你的对象的表达方式,“这就是我如何知道我是否与其他事物相等的方式”,而IEqualityComparer
想象成你的对象的表达方式,“这就是我如何知道其他两个事物是否相等的方式”
有关如何在框架中使用这两个接口的一些好例子,请参见:
- 它实现了
IEquatable
- 它实现了
IEqu