1

私はこれまで辞書を使ったことがなく、もっと知りたいと思っています。

カスタムオブジェクトに関しては、少し迷っています。値ではなく、以下のクラスのようなカスタムオブジェクトをキーとして使用することは可能ですか?

class Car
    {
        public Car(int id, string model)
        {
            ID = id;
            Model = model;
        }

        public int ID { get; private set; }
        public string Model { get; private set; }
    }

あなたが辞書を作成する場所なら、このように:-

 Dictionary<Car, bool> Cars = new Dictionary<Car, bool>();

辞書のコンテンツを検索するときに、Carオブジェクトをキーとしてどのように使用しますか?

4

6 に答える 6

3

はい、これは非常に可能ですが、注意すべき非常に重要な注意事項があります。

辞書は、デフォルトの等価比較を使用してキーをチェックします。カスタムクラスオブジェクトの場合、これは「これは同じオブジェクトへの参照ですか」という意味です。「これは同じデータのオブジェクトですか」ではありません。

したがって、たとえば:

var car1 = new Car(1, "Avalon");
var car2 = car1;
var car3 = new Car(1, "Avalon");

Cars.Add(car1, true);
Console.WriteLine(Cars[car2]); // writes "True";
Console.WriteLine(Cars[car3]); // throws a KeyNotFoundException

GetHashValue()これは、クラスをオーバーライドすることで解決できEquals()ます。ここを参照してください。

于 2013-02-26T16:41:17.330 に答える
3

タイプに対してEquals()とを実装する必要があります。Carは参照型であるため、同じものの異なるインスタンス(両方のCarインスタンスのプロパティは一致しますが、それらは異なるオブジェクトを指します)を辞書に入れても、気付かない可能性があります。GetHashCode()CarCarId

あなたはこれが可能になることを望まない

var carMap = new Dictionary<Car, string>();

var carOne = new Car { Id = 1 };
var careTwo = new Car { Id = 1 };

carMap[carOne] = "one";

// you want this line to fail since a Car with this Id is already present
carMap[carTwo] = "two";

のためGetHasCode()に、あなたは戻ることができますId.GetHashCode()

の場合Equals()、タイプが同じであることを確認するなど、標準の定型文チェックを実行するだけです。

このリンクは、実装する必要がある理由の詳細を提供しますGetHashCode()

于 2013-02-26T16:41:59.473 に答える
2

オブジェクトをキーとして使用するには、オブジェクトのDictionary実装がEqualsありGetHashCode、オブジェクトの「同等性」が何を意味するかを適切に定義することが重要です。

これらの2つのメソッドのデフォルトの実装は、通常は適切ではありません。デフォルトでは、参照を比較するだけなので、同じ値を持つ2つの異なるオブジェクトは、おそらく必要なときに「等しく」なりません。

これらのメソッドの適切な実装ができたら、辞書インデクサーを使用してCarインスタンスを配置し、それに関連付けられたブール値を取得できますCar

于 2013-02-26T16:41:02.100 に答える
2

MSDNから:(http://msdn.microsoft.com/en-us/library/xfhwa508 (v=vs.80).aspx )

If type TKey implements the System.IEquatable generic interface, the default equality comparer uses that implementation.

したがって、あなたの場合IEquatable<Car>、例えば、あなたは実装する必要があります:

   class Car : IEquatable<Car>
    {
        public Car(int id, string model)
        {
            ID = id;
            Model = model;
        }

        public int ID { get; private set; }
        public string Model { get; private set; }

        public bool Equals(Car other)
        {
            return this.ID == other.ID;
        }
    }
于 2013-02-26T16:44:17.847 に答える
1
var car1 = new Car(1,"A300");
var car2 = new Car(1,"A400");

辞書に追加する

   Cars.Add(car1 ,true);
   Cars.Add(car2 ,true);
   Cars.ContainsKey(car1) - //which returns boolean can be used to check for the exisitence of a key

使用できる値を取得するには

   var x=Cars[car1];

ディクショナリコレクションにないキーを使用すると、例外がスローされます。

于 2013-02-26T16:43:34.117 に答える
1

あなたの状況では、カスタムオブジェクトをディクショナリのキーとして使用しようとしています。ディクショナリのデータ構造では、各キーが一意であるため、データ構造で1つのオブジェクトを他のオブジェクトと区別する方法を提供する必要があります。

これは、GetHashCode()メソッドをオーバーライドすることによって行われます。IEquatableの実装はオプションですが、実行しようとしていることを明確にします。

class Car : IEquatable<Car>
    {
        public Car(int id, string model)
        {
            ID = id;
            Model = model;
        }

        public int ID { get; private set; }
        public string Model { get; private set; }

        public bool Equals(Car other)
        {
            return !ReferenceEquals(null, other) && ID == other.ID;
        }
// This is a must if you like to correctly use your object as a key in dictionary
        public override int GetHashCode()
        {
            return ID.GetHashCode();
        }
    }
于 2013-02-26T16:48:21.917 に答える