2011-09-02 19 views
9

संभव डुप्लिकेट:
Modify Struct variable in a Dictionaryअसाइनमेंट

ऐसा क्यों है कि

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

बहुत अच्छा काम करता है, लेकिन

MyDictionary[key].Closed = true; 

"अभिव्यक्ति को संशोधित नहीं कर सकता क्योंकि यह एक चर नहीं है" संकलन समय में त्रुटि दिखाता है?

इन दो मामलों में असाइनमेंट के बारे में अलग क्यों है?

नोट: MyDictionary प्रकार का है <int, MyStruct>

struct के लिए कोड:

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

अधिक कोड दिखाएं .. – Zabba

+0

@Zabba, अधिक कोड के लिए संपादित किया गया। – soandos

+0

डाउनवॉटर टिप्पणी कृपया? – soandos

उत्तर

12

MyDictionary[key] क्योंकि रिटर्न एक struct, यह वास्तव में, संग्रह में वस्तु का एक प्रतिलिपि नहीं लौटा रहा है वास्तविक वस्तु जो तब होती है जब आप कक्षा का उपयोग करते हैं। यह संकलक आपको चेतावनी दे रहा है।

इस हल करने के लिए, आप फिर से स्थापित करने के लिए MyDictionary[key], शायद इस तरह होगा:

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

लेकिन फिर मुझे पूरे कन्स्ट्रक्टर को फिर से कॉल करने की आवश्यकता होगी? इस स्थिति में एक संरचना का हिस्सा बदलने का कोई तरीका नहीं है? – soandos

+0

मैंने अपना उदाहरण संशोधित करने के बजाय एक ही ऑब्जेक्ट का पुन: उपयोग करने के लिए संशोधित किया। – Keith

+1

@soandos संरचना हमेशा विधियों के बीच पारित होने पर प्रतिलिपि बनाई जाती है, इसलिए "संपूर्ण कन्स्ट्रक्टर" हर समय हो रहा है (उदाहरण के लिए जब आप उस स्ट्रोक में कुंजी द्वारा अपनी संरचना तक पहुंचते हैं), इसलिए इसकी अनुशंसा की जाती है कि 16 बाइट्स –

1

बदलें struct एक वर्ग के बजाय होने के लिए ...

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] Iclosed 'हमेशा' dic [0] से स्वतंत्र होगा। संलग्न'। 'Dic [0] = dic [1] कह रहा है; 'दो आइटमों को एक साथ संलग्न किए बिना' dic [0]' की स्थिति कॉपी करेगा। यदि कोई एक उत्परिवर्ती वर्ग का उपयोग करता है, तो कोई व्यक्ति 'डिक [1] लिख सकता है। खुलासा = सत्य;' लेकिन इसका मतलब यह नहीं है कि ऐसा करने से वांछित व्यवहार मिलेगा। एक ऑब्जेक्ट जो संग्रह में आयोजित उत्परिवर्तनीय वस्तुओं के राज्यों में अपने राज्य को समाहित करता है ... – supercat

+0

... आमतौर पर कोड के बाहर प्रश्न पहुंचने के लिए वस्तुओं में किसी भी संदर्भ को देने से बचें।इसका मतलब यह है कि किसी भी आने वाले डेटा को संग्रह में संग्रहीत करने के लिए रक्षात्मक रूप से प्रतिलिपि बनाना, और या तो इसके द्वारा पढ़े गए किसी भी डेटा को रक्षात्मक रूप से प्रतिलिपि बनाना या लपेटना। आंकड़े पढ़ने या लिखने पर स्ट्रक्चर स्वचालित रूप से रक्षात्मक प्रतिलिपि करते हैं, लेकिन किसी भी आकार की संरचना पर कॉपी ऑपरेशन एक ही आकार की कक्षा पर ऐसे परिचालनों से बहुत सस्ता है। लागत में अंतर छोटे structs के लिए सबसे बड़ा है, लेकिन जब तक structs बहुत बड़ा हो जाता है तब तक महत्वपूर्ण बना रहता है। – supercat

संबंधित मुद्दे