3

C# でオブジェクトで構成される辞書を作成することは可能ですKeyか?Valueindex == myDictionary[index].myField

たとえば、標準の C# を想像してみてくださいDictionary。オブジェクトがあるとしCarます:

class Car {
    string name;
    int wheels;
    double weight;
    double horsepower;
    double topSpeed;

    // Appropriate constructors
}

名前でインデックス付けされたこの辞書に保存したいもの:

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

var newCar = Car("Ford", 4, 2387.4, 4535.7, 128.2);
cars["Ford"] = newCar;

次のことができるため、私の基準は保証されません。

cars["Ford"].name = "not Ford";

そして、状態が壊れています。nameからフィールドを単純に削除することはできますCarが、その場合、車自体はそれ自体の名前を認識できなくなります。パフォーマンス コストを別にしても、この時代の車にとっては恥ずかしい状況です。

だから私の質問:ハッシュの値が常にハッシュされた要素の一部と等しくなり、要素が更新されるたびにハッシュが更新されるように、C#でハッシュマップを簡単に作成することは可能ですか?

4

4 に答える 4

2

KeyedCollectionクラスについて説明していますが、コレクションにアイテムを追加した後でアイテムのキーを変更すると、問題が発生します。

プロパティを識別する要素への変更を処理するハッシュコレクションが必要な場合は、タイプ(Car例では)にINotifyPropertyChangedを実装し、必要に応じてコレクションの位置を変更(または削除して再追加)することができます。それは非効率的で、ひどくバグが発生しやすいでしょう。

于 2012-07-30T15:55:29.817 に答える
0

CarDictionary1つの代替方法は、次の行に沿って文字列ベースのインデクサーを使用して独自の指定を作成することです(Nameフィールド/プロパティがであると想定public)。

public class CarDictionary : List<Car>
{
    public Car this[string name]
    {
        get { return this.Single(car => car.Name.Equals(name)); }
        set {
            var oldCar = this.SingleOrDefault(car => car.Name.Equals(name));
            if (oldCar != null) base.Remove(oldCar);
            value.Name = name;
            base.Add(value);
        }
    }

    public new void Add(Car car)
    {
        if (this.Any(c => c.Name.Equals(car.Name))) 
            throw new InvalidOperationException("Dictionary already contains a Car with the same name");
        base.Add(car);
    }
}

さらに、コレクションが誤って破損しないようにAddRange、などの他の基本クラスメソッドを再実装または非表示にする必要があります。Remove

車の「辞書」を初期化し、フォードを追加した場合:

var cars = new CarDictionary();

var newCar = new Car("Ford", 4, 2387.4, 4535.7, 128.2);
cars["Ford"] = newCar;

辞書の状態は次のとおりです。

Number of cars: 1, name of first car: Ford

その後、試してみてください:

cars["Ford"].Name = "not Ford";

辞書の状態は次のようになります。

Number of cars: 1, name of first car: not Ford

次に、再実装されたメソッドを使用して新しいフォードAddを追加します。

cars.Add(new Car("Ford", 6, 4000.0, 500.0, 100.0));

次の辞書の状態が生成されます。

Number of cars: 2, name of last car: Ford

メソッドを使用して別のフォードを追加しようとするAddと、例外が発生します。

var anotherFord = new Car("Ford", 3, 1000.0, 50.0, 120.0);
cars.Add(anotherFord);

InvalidOperationException: Dictionary already contains a Car with the same name

ただし、代わりにインデクサーを使用すると、新しいフォードが古いフォードに置き換わります。

cars["Ford"] = anotherFord;

Number of cars: 2, name of last car: Ford

最後に、インデクサーを使用しCarて辞書に新しいものを追加することの1つの特徴は、インデクサーが追加された名前を変更する可能性があることです(すべきですか?)Car

cars["thought this was a Ford?"] = anotherFord;

Number of cars: 3, name of last car: thought this was a Ford?

私が知る限り、これはインデクサーセッターの予想される動作です。この動作が望ましくない場合は、単に行を削除してください

value.Name = name;

インデクサーセッターの実装から。

于 2012-07-31T07:14:51.647 に答える
0

C# http://msdn.microsoft.com/en-us/library/2549tw02.aspxでインデクサーを使用して実現できます。

于 2012-07-30T15:41:39.247 に答える