C# 如何使用键和值来比较两个KeyValuePair';等于方法?
考虑以下代码:C# 如何使用键和值来比较两个KeyValuePair';等于方法?,c#,C#,考虑以下代码: var a = new KeyValuePair<int, int>(1, 1); var b = new KeyValuePair<int, int>(1, 1); Console.WriteLine(a.Equals(b)); var a=新的KeyValuePair(1,1); var b=新的KeyValuePair(1,1); 控制台写入线(a等于(b)); 输出: 真的 但是,如果我尝试以下代码: class MyClass : IEqu
var a = new KeyValuePair<int, int>(1, 1);
var b = new KeyValuePair<int, int>(1, 1);
Console.WriteLine(a.Equals(b));
var a=新的KeyValuePair(1,1);
var b=新的KeyValuePair(1,1);
控制台写入线(a等于(b));
输出:
真的
但是,如果我尝试以下代码:
class MyClass : IEquatable<MyClass>
{
public MyClass(int myProperty)
{
MyProperty = myProperty;
}
public int MyProperty { get; private set; }
public bool Equals(MyClass other)
{
return other != null &&
MyProperty == other.MyProperty;
}
}
.
.
.
var a = new KeyValuePair<int, MyClass>(1, new MyClass(1));
var b = new KeyValuePair<int, MyClass>(1, new MyClass(1));
Console.WriteLine(a.Equals(b));
类MyClass:IEquatable
{
公共MyClass(int myProperty)
{
MyProperty=MyProperty;
}
public int MyProperty{get;private set;}
公共布尔等于(MyClass其他)
{
返回其他!=null&&
MyProperty==other.MyProperty;
}
}
.
.
.
var a=新的KeyValuePair(1,新的MyClass(1));
var b=新的KeyValuePair(1,新的MyClass(1));
控制台写入线(a等于(b));
那么输出是:
假的
我的结论是,因为键是值类型,所以它们按值进行比较,因为值是引用类型,所以它们按引用进行比较
我想比较KeyValuePair
的方式是通过值来比较值(以及键),即使用我提供的Equals
方法
我如何才能做到这一点?重写Equals方法
public override bool Equals(object obj)
{
MyClass other = obj as MyClass;
return other != null &&
MyProperty == other.MyProperty;
}
编辑:如注释中所述,每当重写Equals方法时,您还需要重写该方法。不这样做将导致在重写的Equals方法上显示a,以及其他问题。重写Equals方法
public override bool Equals(object obj)
{
MyClass other = obj as MyClass;
return other != null &&
MyProperty == other.MyProperty;
}
编辑:如注释中所述,每当重写Equals方法时,您还需要重写该方法。不这样做将导致在重写的Equals方法上显示a,以及其他问题。您可以在MyClass中重写compare并决定比较的工作方式。我想,您需要重写默认方法
bool Equals(对象o)
,并从中调用您的IEquatable。看一看您可以在MyClass中重写compare并决定比较是如何工作的。我想,您需要重写默认方法bool Equals(object o)
,并从中调用您的IEquatable。看一看,public override int GetHashCode()
是的,如果将对象粘贴到任何类型的集合中,不重写GetHashCode()
几乎肯定会导致问题。@zzxyz不是任何类型的集合。特别是一个基于散列的集合。但是,是的,您应该始终重写GetHashCode以与Equals
同步,因为在基于哈希的集合中使用类型时未能这样做的后果非常糟糕。@Servy bad…不幸的是…通常有点微妙。而且大多数集合并不保证它们不使用散列。@zzxyz当然,几乎没有任何东西能保证它不使用什么。你只需要关心那些说他们确实在使用它的东西。任何没有特别提到它正在使用散列的东西都不应该期望其中的对象具有有用的散列。在.NET中,实际上只有两个集合使用哈希函数,Dictionary和HashSet。而且public override int GetHashCode()
是的,如果将对象粘贴在任何类型的集合中,不重写GetHashCode()
几乎肯定会导致问题。@zzxyz不是任何类型的集合。特别是一个基于散列的集合。但是,是的,您应该始终重写GetHashCode以与Equals
同步,因为在基于哈希的集合中使用类型时未能这样做的后果非常糟糕。@Servy bad…不幸的是…通常有点微妙。而且大多数集合并不保证它们不使用散列。@zzxyz当然,几乎没有任何东西能保证它不使用什么。你只需要关心那些说他们确实在使用它的东西。任何没有特别提到它正在使用散列的东西都不应该期望其中的对象具有有用的散列。在.NET中,实际上只有两个集合使用了哈希函数:字典和哈希集。