2011-09-02 72 views
9

可能重複:
Modify Struct variable in a Dictionary分配的領域/屬性

爲什麼是它

MyStruct test = new MyStruct(); 
    test.Closed = true; 

偉大的作品,但

MyDictionary[key].Closed = true; 

在編譯時顯示「無法修改表達式,因爲它不是變量」錯誤?

爲什麼在這兩種情況下的分配有所不同?

注:MyDictionary類型爲<int, MyStruct>

代碼的結構:

public struct MyStruct 
{ 
    //Other variables 
    public bool Isclosed; 
    public bool Closed 
    { 
     get { return Isclosed; } 
     set { Isclosed = value; } 
    } 
//Constructors 
} 
+0

顯示更多的代碼.. – Zabba

+0

@Zabba,編輯更多的代碼。 – soandos

+0

Downvoter評論請嗎? – soandos

回答

12

因爲MyDictionary[key]返回一個結構,它是真正返回對象的副本集合中,而不是實際的對象,當你使用一個類時會發生什麼。這是編譯器警告你的。

要解決這個問題,你必須重新設置MyDictionary[key],也許是這樣的:

var tempObj = MyDictionary[key]; 
tempObj.Closed = true; 
MyDictionary[key] = tempObj; 
+0

但是,然後我需要再次調用整個構造函數沒有?在這種情況下沒有辦法改變結構的一部分? – soandos

+0

我修改了我的示例以重用相同的對象,而不是創建一個新對象。 – Keith

+1

@soandos結構在方法之間傳遞時總是被複制,所以「整個構造函數」一直在發生(例如當你通過那個dict中的鍵訪問你的結構時),這就是爲什麼它建議不要有大於16字節的結構 –

1

更改結構爲一類,而不是...

class Program 
{ 
    static void Main(string[] args) 
    { 
     dic = new Dictionary<int, MyStruct>(); 

     MyStruct s = new MyStruct(){ Isclosed=false}; 

     dic.Add(1,s); 

     dic[1].Isclosed = true; 

     Console.WriteLine(dic[1].Isclosed.ToString()); //will print out true... 
     Console.Read(); 
    } 

    static Dictionary<int, MyStruct> dic; 

    public class MyStruct 
    { 
     public bool Isclosed; 
     public bool Closed 
     { 
      get { return Isclosed; } 
      set { Isclosed = value; } 
     } 
    } 
} 
+0

我知道結構在處理幾個基本上包含像結構這樣的字段的對象時效率更高,但如果碰巧只是實例化一些對象,那麼創建一個類將爲您節省一些代碼:) –

+0

當使用暴露字段結構使用除數組之外的內置集合,必須複製該結構,對其進行修改,然後將其存回。麻煩,但語義是可以預測的; 'dic [1] .Isclosed'將總是獨立於'dic [0] .Isclosed'。說'dic [0] = dic [1];'將複製'dic [0]'的狀態而不附加兩個項目在一起。如果使用可變類,可以寫'dic [1] .Isclosed = true;'但這並不意味着這樣做會產生所需的行爲。一個將其狀態封裝在一個集合中的可變對象狀態中的對象必須... – supercat

+0

...通常避免讓任何對有問題的對象的引用到達外部代碼。這意味着防禦性地複製要存儲在集合中的任何傳入數據,並且防禦性地複製或包裝從其讀取的任何數據。在讀取或寫入數據時,結構會自動執行防禦性複製,但對任何大小的結構進行復制操作比在相同大小的類上進行復制操作要便宜得多。小結構的成本差異最大,但在結構變得非常大之前仍然很重要。 – supercat