これはこれに対するフォローアップの質問です: List<T>.Contains と T[].Contains の動作が異なります
T[].Contains
T
クラスと構造体の場合、動作が異なります。この構造体があるとします:
public struct Animal : IEquatable<Animal>
{
public string Name { get; set; }
public bool Equals(Animal other) //<- he is the man
{
return Name == other.Name;
}
public override bool Equals(object obj)
{
return Equals((Animal)obj);
}
public override int GetHashCode()
{
return Name == null ? 0 : Name.GetHashCode();
}
}
var animals = new[] { new Animal { Name = "Fred" } };
animals.Contains(new Animal { Name = "Fred" }); // calls Equals(Animal)
ここでは、予想どおりジェネリックEquals
が正しく呼び出されます。
しかし、クラスの場合:
public class Animal : IEquatable<Animal>
{
public string Name { get; set; }
public bool Equals(Animal other)
{
return Name == other.Name;
}
public override bool Equals(object obj) //<- he is the man
{
return Equals((Animal)obj);
}
public override int GetHashCode()
{
return Name == null ? 0 : Name.GetHashCode();
}
}
var animals = new[] { new Animal { Name = "Fred" } };
animals.Contains(new Animal { Name = "Fred" }); // calls Equals(object)
非ジェネリックEquals
が呼び出され、`IEquatable を実装する利点が失われます。
両方のコレクションがジェネリックに見えるのに、との配列の呼び出しがEquals
異なるのはなぜですか?struct[]
class[]
配列の奇妙さは非常にイライラするので、完全に回避しようと考えています...
注:のジェネリック バージョンは、構造体が を実装Equals
する場合にのみ呼び出されます。型が を実装していない場合、またはであるかどうかに関係なく、 の非ジェネリック オーバーロードが呼び出されます。IEquatable<T>
IEquatable<T>
Equals
class
struct