dar*_*624 19 c# equality equals iequalitycomparer gethashcode
当我使用字典有时我必须更改默认的等于意思,以便比较键.我看到如果我在键的类上重写Equals和GetHashCode,或者我创建了一个实现IEqualityComparer的新类,我有相同的结果.那么使用IEqualityComparer和Equals/GethashCode Override有什么区别?两个例子:
class Customer
{
public string name;
public int age;
public Customer(string n, int a)
{
this.age = a;
this.name = n;
}
public override bool Equals(object obj)
{
Customer c = (Customer)obj;
return this.name == c.name && this.age == c.age;
}
public override int GetHashCode()
{
return (this.name + ";" + this.age).GetHashCode();
}
}
class Program
{
static void Main(string[] args)
{
Customer c1 = new Customer("MArk", 21);
Customer c2 = new Customer("MArk", 21);
Dictionary<Customer, string> d = new Dictionary<Customer, string>();
Console.WriteLine(c1.Equals(c2));
try
{
d.Add(c1, "Joe");
d.Add(c2, "hil");
foreach (KeyValuePair<Customer, string> k in d)
{
Console.WriteLine(k.Key.name + " ; " + k.Value);
}
}
catch (ArgumentException)
{
Console.WriteLine("Chiave già inserita in precedenza");
}
finally
{
Console.ReadLine();
}
}
}
Run Code Online (Sandbox Code Playgroud)
}
第二个 :
class Customer
{
public string name;
public int age;
public Customer(string n, int a)
{
this.age = a;
this.name = n;
}
}
class DicEqualityComparer : EqualityComparer<Customer>
{
public override bool Equals(Customer x, Customer y) // equals dell'equalitycomparer
{
return x.name == y.name && x.age == y.age;
}
public override int GetHashCode(Customer obj)
{
return (obj.name + ";" + obj.age).GetHashCode();
}
}
class Program
{
static void Main(string[] args)
{
Customer c1 = new Customer("MArk", 21);
Customer c2 = new Customer("MArk", 21);
DicEqualityComparer dic = new DicEqualityComparer();
Dictionary<Customer, string> d = new Dictionary<Customer, string>(dic);
Console.WriteLine(c1.Equals(c2));
try
{
d.Add(c1, "Joe");
d.Add(c2, "hil");
foreach (KeyValuePair<Customer, string> k in d)
{
Console.WriteLine(k.Key.name + " ; " + k.Value);
}
}
catch (ArgumentException)
{
Console.WriteLine("Chiave già inserita in precedenza");
}
finally
{
Console.ReadLine();
}
}
}
Run Code Online (Sandbox Code Playgroud)
}
两个例子都有相同的结果.
提前致谢.
Bru*_*oLM 14
当您覆盖Equals并且GetHashCode您正在更改对象将确定它是否等于另一个对象的方式时.还有一个注意事项,如果使用==运算符比较对象,则Equals除非您重写运算符,否则它将具有相同的行为.
这样做就改变了单个类的行为,如果你需要为其他类提供相同的逻辑呢?如果您需要"通用比较".这就是你拥有的原因IEqualityComparer.
看看这个例子:
interface ICustom
{
int Key { get; set; }
}
class Custom : ICustom
{
public int Key { get; set; }
public int Value { get; set; }
}
class Another : ICustom
{
public int Key { get; set; }
}
class DicEqualityComparer : IEqualityComparer<ICustom>
{
public bool Equals(ICustom x, ICustom y)
{
return x.Key == y.Key;
}
public int GetHashCode(ICustom obj)
{
return obj.Key;
}
}
Run Code Online (Sandbox Code Playgroud)
我有两个不同的类,都可以使用相同的比较器.
var a = new Custom { Key = 1, Value = 2 };
var b = new Custom { Key = 1, Value = 2 };
var c = new Custom { Key = 2, Value = 2 };
var another = new Another { Key = 2 };
var d = new Dictionary<ICustom, string>(new DicEqualityComparer());
d.Add(a, "X");
// d.Add(b, "X"); // same key exception
d.Add(c, "X");
// d.Add(another, "X"); // same key exception
Run Code Online (Sandbox Code Playgroud)
请注意,我没有覆盖Equals,GetHashCode在既没有类.我可以在任何实现的对象中使用此比较器,ICustom而无需重写比较逻辑.我也可以创建IEqualityComparer一个"父类"并使用继承的类.我可以让比较器以不同的方式运行,我可以做一个比较Value而不是Key.
因此,IEqualityComparer允许更多灵活性,您可以实现通用解决方案
| 归档时间: |
|
| 查看次数: |
10752 次 |
| 最近记录: |