namespace Dic
{
public class Key
{
string name;
public Key(string n) { name = n; }
}
class Program
{
static string Test()
{
Key a = new Key("A");
Key b = new Key("A");
System.Collections.Generic.Dictionary<Key, int> d = new System.Collections.Generic.Dictionary<Key, int>();
d.Add(a, 1);
return d.ContainsKey(b).ToString();
}
static void Main(string[] args)
{
System.Console.WriteLine(Test());
}
}
}
我应该改变什么来实现?
答案 0 :(得分:35)
你想要真实 - 但a和b是不同的对象。
您需要在类Key
上覆盖GetHashCode和Equalspublic class Key
{
string name;
public Key(string n) { name = n; }
public override int GetHashCode()
{
if (name == null) return 0;
return name.GetHashCode();
}
public override bool Equals(object obj)
{
Key other = obj as key;
return other != null && other.name == this.name;
}
}
答案 1 :(得分:8)
如果你覆盖Key.GetHashCode和Key.Equals,那可能会有所帮助。
在Key
:
public override bool Equals(object obj)
{
var k = obj as Key;
if (k != null)
{
return this.name == k.name;
}
return base.Equals(obj);
}
public override int GetHashCode()
{
return this.name.GetHashCode();
}
答案 2 :(得分:6)
如果你没有能力像其他人提到的那样覆盖相等的运算符/ Equals / GetHashCode(例如,你没有控制对象的源代码),你可以提供IEqualityComparer<Key>
实现。字典的构造函数,用于执行相等性检查。
class KeyComparer : IEqualityComparer<Key>
{
public bool Equals(Key x, Key y)
{
return x.Name == y.Name;
}
public int GetHashCode(Key obj)
{
return obj.Name.GetHashCode();
}
}
就目前而言,你的Key是一个引用对象,所以除非你告诉世界(或字典),否则只能在引用时确定相等。
答案 3 :(得分:4)
重写类'GetHashCode和Equals方法以使其在字典中正常工作不是一个非常好的方法。字典的行为方式应该是字典的实现细节,而不是用作键的任何类。当你想在具有不同行为的不同词典中使用该类时,你会遇到麻烦。或者,如果您无权访问类源代码。
更好的鼠标陷阱是为字典提供自己的比较器。例如:
using System;
using System.Collections.Generic;
class Program {
static void Main(string[] args) {
var d = new Dictionary<Key, int>(new MyComparer());
d.Add(new Key("A"), 1);
Console.WriteLine(d.ContainsKey(new Key("a")));
Console.ReadLine();
}
private class MyComparer : IEqualityComparer<Key> {
public bool Equals(Key x, Key y) {
return string.Compare(x.Name, y.Name, true) == 0;
}
public int GetHashCode(Key obj) {
return obj.Name.ToUpper().GetHashCode();
}
}
public class Key {
public string Name { get; set; }
public Key(string name) { Name = name; }
}
}
答案 4 :(得分:2)
为了将您自己的类用作字典键,您应该重写GetHashCode和Equals。否则,它将使用内存地址来检查是否相等。
public class Key { string name; public Key(string n) { name = n; } public override int GetHashCode() { return name.GetHashCode(); } public override bool Equals(object obj) { var other = obj as Key; if( other == null ) return false; return name == other.name; } }
答案 5 :(得分:1)
你的问题是那个
new Key("A").Equals(new Key("A"))==false.
和
new Key("A").GetHashCode()!=new Key("A").GetHashCode()
解决这个问题,我觉得应该可行。要修复它,请覆盖Equals方法并检查名称值是否相同。如果要覆盖Equals,还应该覆盖GetHashCode。
答案 6 :(得分:1)
您需要覆盖Key类的Equals和GetHashCode方法。
答案 7 :(得分:0)
它们内部具有相同的值但是!= b,因为它们是2个不同的变量。
答案 8 :(得分:0)
您需要覆盖Key类的Equals
和GetHashCode
方法。在您的情况下,您可以根据密钥的名称进行比较(如果您的类更复杂,则可以在任何其他独特属性上进行比较)。
public class Key {
string name;
public Key(string n) { name = n; }
public override bool Equals(object obj) {
Key k = obj as Key;
if (k == null)
return false;
return name.Equals(k.name);
}
public override int GetHashCode() {
return name.GetHashCode();
}
}
答案 9 :(得分:0)
<强> 1。覆盖等于,获取哈希代码和'=='运算符。
Key类必须覆盖Equals
,以便Dictionary检测它们是否相同。默认实现仅检查引用。
下面:
public bool Equals(Key other)
{
return this == other;
}
public override bool Equals(object obj)
{
if (obj == null || !(obj is Key))
{
return false;
}
return this.Equals((Key)obj);
}
public static bool operator ==(Key k1, Key k2)
{
if (object.ReferenceEquals(k1, k2))
{
return true;
}
if ((object)k1 == null || (object)k2 == null)
{
return false;
}
return k1.name == k2.name;
}
public static bool operator !=(Key k1, Key k2)
{
if (object.ReferenceEquals(k1, k2))
{
return false;
}
if ((object)k1 == null || (object)k2 == null)
{
return true;
}
return k1.name != k2.name;
}
public override int GetHashCode()
{
return this.name == null ? 0 : this.name.GetHashCode();
}
<强> 2。如果可能,请使用结构。
您应该使用这样的不可变数据类型的结构,因为它们是按值传递的。这意味着您不会意外地将两个不同的值混合到同一个键中。
答案 10 :(得分:0)
然后你需要在Key类上覆盖GetHashCode和Equals。
如果不这样做,您将获得两者的默认实现。这导致a和b的哈希码很可能不一样(我不知道默认实现是怎么样的),而a肯定不等于b(默认的Equals()实现检查引用相等)。
在您的情况下,假设“name”不是null,它可以实现为
public class Key
{
string name;
public override int GetHashCode()
{
return name.GetHashCode();
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
Key objAsKey = obj as Key;
if (objAsKey == null)
{
return false;
}
return this.name.Equals(objAsKey.Name);
}
}
这是否是一个令人满意的哈希是一个不同的故事,但它显示了原则,但是。
答案 11 :(得分:-1)
在这种情况下,ContainsKey将Key作为对象进行比较,并检查对象本身是否相同 - 它们不是。你需要实现IComparable或覆盖Key.Equals或类似的东西,以使它做你想要的。