私がよく遭遇する問題は、そのオブジェクトの一意の「インデックス」である特定のフィールド/プロパティによってそれらを取得できるように、オブジェクトのコレクションを格納する必要があることです。たとえばPerson
、フィールドが一意の識別子であるオブジェクトがあり、そのオブジェクトのname
コレクションから取得できるようにしたいと考えています。Java では通常、実際に が必要な場所で を使用し、常にオブジェクトの「インデックス」フィールドをマップ内のキーとして使用して、これを実現します。次のように、C#でsを使用して同じことを行うことを考えていました:Person
Person
name="Sax Russell"
Map
Set
peopleMap.add(myPerson.getName(), myPerson)
Dictionary
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 in names) {
person = people[name];
//process person somehow...
}
}
ただし、これは扱いにくいように思われ、 のキーDictionary
とその値の間の結合がかなり緩くなります。各 を格納するキーとしてプロパティをPerson
使用する辞書のすべてのプロデューサーに暗黙的に依存しています。ディクショナリにアクセスするたびに再確認しない限り、要素 atが実際にwithであるという保証はありません。Name
Person
people["Sax Russell"]
Person
Name="Sax Russell"
Person
カスタム等値比較子や LINQ クエリを使用して、オブジェクトのコレクションが名前でインデックス付けされていることを明示的に確認する方法はありますか? List.Find
ルックアップが一定時間維持されることが重要です。そのため、 orだけを使用することはできませんEnumerable.Where
。HashSet
を使用して、指定されたオブジェクトのフィールドのみを比較する等値比較器で構築しようとしましたが、名前だけを使用してオブジェクトをName
取得する方法はないようです。Person