私がよく遭遇する問題は、オブジェクトのコレクションを、そのオブジェクトの一意の「インデックス」である特定のフィールド/プロパティによって取得できるように格納する必要があることです。たとえば、name
フィールドが一意の識別子であるPerson
オブジェクトがあり、Person
オブジェクトのコレクションからのname="Sax Russell"
を取得できるようにしたいと考えています。 Javaでは通常Map
を使って実際にSet
が必要ですが、マップのキーとしてオブジェクトの「インデックス」フィールドを常に使用しています。すなわち、peopleMap.add(myPerson.getName(), myPerson)
です。私はこのように、Dictionary
SとC#で同じことをやって考えていた:C#コレクションはプロパティによってインデックス付けされていますか?
class Person {
public string Name {get; set;}
public int Age {get; set;}
//...
}
Dictionary<string, Person> PersonProducerMethod() {
Dictionary<string, Person> people = new Dictionary<string, Person>();
//somehow produce Person instances...
people.add(myPerson.Name, myPerson);
//...
return people;
}
void PersonConsumerMethod(Dictionary<string, Person> people, List<string> names) {
foreach(var name : names) {
person = people[name];
//process person somehow...
}
}
しかし、これは不器用なようだ、とDictionary
のキーとその値の間にかなりの疎結合を紹介します。私は暗黙のうちに、それぞれPerson
を格納するキーとしてName
プロパティを使用してPerson
辞書のすべてのプロデューサに依存しています。 people["Sax Russell"]
の要素が実際にPerson
のName="Sax Russell"
であるという保証はありません。辞書にアクセスするたびに再確認しない限りです。
Person
オブジェクトのコレクションがカスタム等価比較者またはLINQクエリを使用して名前でインデックス付けされることを明示的に確認する方法がいくつかありますか。ルックアップは一定時間滞在することが重要です。そのため、私はList.Find
またはEnumerable.Where
を使用できません。私はHashSet
を使って試してみましたが、指定されたオブジェクトのName
フィールドだけを比較する等価比較器で構築しましたが、Person
オブジェクトを名前だけで検索する方法はありません。
はちょうどこのつまずいていますが、[KeyedCollection](httpsを検討しています: //msdn.microsoft.com/en-us/library/ms132438(v=vs.110).aspx)class? – ygoe