2012-02-15 123 views
2

我正在爲我的任務寫一個自定義字典類,但它給錯誤。這個班有什麼問題?謝謝爲什麼這個自定義字典類不工作 - C#4.0

 public struct MyValue 
    { 
     public int irValue1; 
     public int irValue2; 
    } 

    public class csCustomDictionary : Dictionary<string, MyValue> 
    { 
     public void Add(string srKey, int irVal1, int irVal2) 
     { 
      if (this.ContainsKey(srKey) == true) 
      { 
       this[srKey].irValue1 = this[srKey].irValue1 + irVal1; 
       this[srKey].irValue1 = this[srKey].irValue2 + irVal2; 
      } 
      else 
      { 
       MyValue val; 
       val.irValue1 = irVal1; 
       val.irValue2 = irVal2; 
       this.Add(srKey, val); 
      } 
     } 
    } 
} 

這是錯誤消息

enter image description here

C#4.0

這是修改後的版本正確

public class csMyValue 
{ 
    public int irValue1; 
    public int irValue2; 
} 

public class csCustomDictionary : Dictionary<string, csMyValue> 
{ 
    public void Add(string srKey, int irVal1, int irVal2) 
    { 
     if (this.ContainsKey(srKey) == true) 
     { 
      this[srKey].irValue1 = this[srKey].irValue1 + irVal1; 
      this[srKey].irValue1 = this[srKey].irValue2 + irVal2; 
     } 
     else 
     { 
      csMyValue val = new csMyValue(); 
      val.irValue1 = irVal1; 
      val.irValue2 = irVal2; 
      this.Add(srKey, val); 
     } 
    } 
} 
+1

* *什麼錯誤?它在哪裏?你有例外嗎?它沒有按預期執行嗎?不要讓我們成爲偵探。 – 2012-02-15 00:50:31

+0

添加了錯誤圖像。請刷新並重新檢查 – MonsterMMORPG 2012-02-15 00:53:56

+2

您是否知道只需單擊該錯誤並按F1即可獲取此幫助頁面? [編譯器錯誤CS1612](http://msdn.microsoft.com/en-us/library/wydkhw2c(v = vs.100).aspx) – 2012-02-15 00:59:35

回答

3

問題是你在字典中使用了struct作爲你的值。

當您編寫:this[srKey]時,您實際上會檢索存儲爲字典值的結構的副本。因此,.irValue1正試圖在副本上設置一個字段(即將消失)。

如果您將MyValue更改爲類,則應該可以工作。這也更合適,因爲你正在製作一個可變類型,而可變結構很少是一個好主意。

話雖這麼說,你可能會迫使該通過製作一個臨時的工作,設置領域,然後在你的字典設定值:

if (this.ContainsKey(srKey) == true) 
{ 
    MyValue tmp = this[srKey]; 
    tmp.irValue1 += irVal1; 
    tmp.irValue2 += irVal2; 
    this[srKey] = tmp; 
} 

如果更改MyValue是一類的,而不是一個結構,你可以寫:

MyValue tmp = this[srKey]; 
    tmp.irValue1 += irVal1; 
    tmp.irValue2 += irVal2; 

由於存儲的值將是一個參考,這是不行的,你想,而不需要大量的字典查找的變化。

+0

非常感謝您的回答。我修改了問題並添加了類版本。這會工作好嗎?還是有更好的方法? – MonsterMMORPG 2012-02-15 01:04:47

+1

@MonsterMMORPG類的版本將工作 - 但讀了我的最後一節;)它顯示了一個更好的版本使用類(獲得一個tmp,增量),因爲它不必做字典查找4次,只是一次。 – 2012-02-15 01:11:27

+0

因此,而不是如果我會只使用你的版本的權利?或者只是更換內部如果檢查? – MonsterMMORPG 2012-02-15 01:16:42

1

我想這是說this[whatever]不能在任務的左側。試試這個:

public class csCustomDictionary : Dictionary<string, MyValue> 
{ 
    public void Add(string srKey, int irVal1, int irVal2) 
    { 
     if (this.ContainsKey(srKey) == true) 
     { 
      var myVal = this[srKey]; 
      myVal.irValue1 = myVal.irValue1 + irVal1; 
      myVal.irValue1 = myVal.irValue2 + irVal2; 
     } 
     else 
     { 
      MyValue val; 
      val.irValue1 = irVal1; 
      val.irValue2 = irVal2; 
      this.Add(srKey, val); 
     } 
    } 
} 
+1

這將編譯,但實際上並沒有更改字典中的值...你的改變使得這是一個無操作。 – 2012-02-15 00:59:06

+0

但它也揭示*爲什麼* C#不會讓你這樣做:) – porges 2012-02-15 01:00:04

+0

裏德,這絕對不是真的。內存中只有一個對象的副本。 – Diego 2012-02-15 02:00:17

1

C#不會讓你這樣做,因爲MyValue是一個結構體。

this[...]方法將返回數據的副本,所以如果您更改該字段,它將不會執行任何操作。

改爲改爲類。

如果你真的需要它是一個結構,你可以這樣做:

var tmp = this[srKey]; 
tmp.irValue1 += irVal1; 
this[srKey] = tmp; 
+0

非常感謝您的回答。我修改了問題並添加了類版本。這會工作好嗎?還是有更好的方法? – MonsterMMORPG 2012-02-15 01:05:05

1

當使用索引你實際上是讓你MyValue的副本,因爲它是一個結構類型。編譯器實際上幫助你,讓你知道代碼沒有達到你的期望。要解決此問題,您需要直接指定一個新值。

var current = this[srKey]; 
this[srKey] = new MyValue { 
    irValue1 = current.irValue1 + irVal1, 
    irValue2 = current.irValue2 + irVal2 
}; 
0

要創建自定義詞典,你需要從IDictionary <int, MyValue>繼承和實現接口,添加(),刪除()等