2012-07-30 62 views
3

是否可以在C#中創建由對象組成的字典,以使Key只是對字段值的引用(或字段爲Value ,因爲它是),所以這是保證index == myDictionary[index].myFieldDictionary <myField,myObject>其中myField是myObject的成員

例如,想象一個標準的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"; 

並且條件被破壞。我可以簡單地從Car中刪除字段,但是汽車本身並不知道它自己的名字 - 即使在我們擱置性能成本的情況下,這個時代的汽車也是令人尷尬的情況。

所以我的問題:是否有可能在C#中輕鬆製作哈希映射,使哈希值始終等於散列元素的某個部分,並且只要元素是哈希值就更新?

+0

'散列更新'如果你已經存儲在一個散列表...你會怎麼建議這應該工作?這聽起來像一本字典可能不是你想要的結構。 – asawyer 2012-07-30 15:42:38

+1

散列應該是不可變的任何對象。它必須基於定義對象身份的字段。在'Equals(object)'方法中測試的相同。否則不能更改散列,否則將無法在字典中找到您的密鑰。 – Seb 2012-07-30 15:46:31

回答

0
+0

索引器可能是有用的,但這不是這個問題的答案。如何使用索引器? – svick 2012-07-30 15:59:47

+0

@svick如果您查看鏈接中的類TempRecord示例。我在想這是否可以作爲字典 – HatSoft 2012-07-30 16:05:52

+0

請我可以請求解釋-1 – HatSoft 2012-07-30 16:15:33

0

你可以考慮到一流的設計改變來實現它:

class Car { public string name { get; private set; } } 

因此,你將無法改變該標識的一部分物體。否則,字典似乎是一個好方法。

2

您正在描述KeyedCollection類,但如果在將項添加到集合後更改項目的鍵,則會出現問題。

如果你想有一個哈希集合來處理其元素標識屬性的變化,你可以在類型上實現INotifyPropertyChanged(在你的例子中爲Car),並讓集合重新定位項目(或刪除並重新添加它們)如所須。這將是低效的,非常容易出錯。

+1

這是一個'抽象'類。你能解釋一下在這種情況下你將如何使用它? – svick 2012-07-30 15:58:48

+0

@svick通過派生一個具體的類,與任何抽象類相同。 – phoog 2012-07-30 16:02:13

0

一種替代的方法來構建自己的指定CarDictionary與大致如下(假設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添加到字典的是,至於我可以告訴這個

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

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

將是預期的行爲○:索引可能會(?應該)改變加Car的名字f分度器設定器。如果這種行爲是不希望的,只需從索引器設置器實現中刪除線

value.Name = name; 

相關問題