これは私たちが遭遇する一般的な問題だと思います。
class Person
{
public string place;
public string name;
public Person(string place, string name)
{
this.place = place;
this.name = name;
}
public bool Equals(Person other)
{
if (ReferenceEquals(null, other))
return false;
return name == other.name;
}
public override bool Equals(object obj)
{
return Equals(obj as Person);
}
public override int GetHashCode()
{
return name.GetHashCode();
}
public override string ToString()
{
return place + " - " + name;
}
}
このクラスがあるとします。KeyedCollection
次のように実装できます。
class Collection : KeyedCollection<string, Person>
{
protected override string GetKeyForItem(Person item)
{
return item.place;
}
}
ここでは、デフォルトEquals
は に基づいてname
いますPerson
が、私の場合はごとcollection
に 1 つだけのカスタムを作成しています。つまり、 で一意になります。Person
place
place
collection
Person p1 = new Person("Paris", "Paul");
Person p2 = new Person("Dubai", "Ali");
var collection = new Collection { p1, p2 };
var p3 = new Person("Paris", "Jean");
if (!collection.Contains(p3))
collection.Add(p3); // explosion
私は問題を理解しています。オーバーContains(Person)
ロードは、重複キー例外を引き起こす可能性がある内部ディクショナリに値を追加しCollection<T>.Contains(T)
ながら、値ベースの線形検索を行うものです。Add(Person)
ここで、等式が に基づいてplace
いれば、この問題は存在しなかったでしょう。
回避策があります:
class Collection : KeyedCollection<string, Person>
{
protected override string GetKeyForItem(Person item)
{
return item.place;
}
new public bool Contains(Person item)
{
return this.Contains(GetKeyForItem(item));
}
}
しかし、これもまた、一般的なことを行う場合を意味します
var p3 = new Person("Paris", "Jean");
bool b = collection.Contains(p3); //true
を返しますtrue
が、実際にはまだJean
存在しcollection
ません。だから私の質問は、の一部だけに基づいているKeyedCollection<K, T>
場合にのみ意味がありますか? 私の質問はセマンティクス側ではほとんどありません。私は解決策を求めているわけではありませんが、いつ意味があるかについて一般的な理解があることを知っているだけですか? ドキュメントから、この件に関連するものは見つかりませんでした。Equals
K
T
KeyedCollection
アップデート:
ここで言及されている正確な問題を見つけましたhttp://bytes.com/topic/net/answers/633980-framework-bug-keyedcollection-t
質問者がバグレポートを MS に提出した場所。彼の言葉を引用すると (2007 年 4 月 18 日付け):
私はこれをバグとして Microsoft に提出しましたが、Microsoft はそれを確認して受け入れました。これは問題 ID 271542 で、次の場所で追跡できます。
「WinXP pro SP2 および VSTS2005 SP1 でこのバグを再現しました。このバグを Visual Studio 製品チーム内の適切なグループに送信して、トリアージと解決を図っています。」
これはバグではないと思いますが、これは確かに迷惑です。しかし、そもそも MS がこれをバグとしてどのように受け入れたのか疑問に思っています (おそらく、ページは現在見つかりません)。Imo、その継承モデルはよく考えられていません。