2010-11-14 12 views
13

फार्म पर एक सदस्य को एक्सेस करना एक क्रम अपवाद का कारण हो सकता का एक क्षेत्र है एक क्रम अपवाद का कारण हो सकता है क्योंकि यह एक का एक क्षेत्र है मार्शल-दर- संदर्भ वर्गफार्म पर एक सदस्य को एक्सेस करना है क्योंकि यह एक मार्शल-दर-संदर्भ वर्ग

मुझे पता है कि यह चेतावनी क्या है और इसे हल करने का तरीका जानें।

मेरा प्रश्न यह है कि यह रनटाइम त्रुटि क्यों कर सकता है?

+0

संदर्भ क्या है जहां आपको यह चेतावनी मिलती है? –

उत्तर

23

आप शायद चेतावनी CS1690, रेप्रो कोड के बारे में बात कर रहे हैं:

public class Remotable : MarshalByRefObject { 
    public int field; 
} 
public class Test { 
    public static void Run() { 
     var obj = new Remotable(); 
     // Warning CS1690: 
     Console.WriteLine(obj.field.ToString()); 
    } 
} 

एक दूरस्थ परिदृश्य में, Test.Run विधि Remotable वस्तु के एक प्रॉक्सी के साथ काम करेंगे। किसी संपत्ति, विधि या घटना के लिए प्रॉक्सी बनाना कोई समस्या नहीं है, केवल एक विधि बनाने योग्य है जिसमें विकल्प शामिल हैं। फ़ील्ड एक समस्या है हालांकि, 'हुक' करने के लिए कुछ भी नहीं है। एमबीआरओ के लिए, जेआईटी कंपाइलर अब सीधे क्षेत्र तक पहुंचने के लिए कोड उत्पन्न नहीं करता है, यह इस मामले में सीएलआर, JIT_GetField32() में निर्मित एक सहायक विधि के लिए कॉल इंजेक्ट करता है।

वह सहायक जांच करता है कि ऑब्जेक्ट प्रॉक्सी है और रिमोट वैल्यू प्राप्त करने के लिए रीमोटिंग प्लंबिंग का उपयोग करता है यदि ऐसा है। या अगर यह नहीं है तो सीधे क्षेत्र को सीधे एक्सेस करता है। ToString() कॉल करना हालांकि मूल्य को बॉक्स किए जाने की आवश्यकता है। यह एक समस्या है, मुक्केबाजी प्रॉक्सी से मूल्य अलग करता है। यह सुनिश्चित करने का कोई तरीका नहीं है कि बॉक्स किए गए मान हमेशा रिमोट किए गए मान की एक सटीक प्रति है। जब भी ToString() विधि स्ट्रिंग को प्रारूपित करने के लिए मान का उपयोग करती है तो JIT_GetField32() को कॉल करना संभव नहीं है।

सीएस 16 9 0 के लिए कामकाज सरल है, एक संपत्ति के साथ क्षेत्र को लपेटने से परे, बस स्थानीय चर में फ़ील्ड मान की प्रतिलिपि बनाएँ। अब यह क्रिस्टल स्पष्ट है कि कोड एक प्रतिलिपि के साथ काम कर रहा है और कभी आश्चर्य नहीं होता है इसलिए संकलक को चेतावनी को छोड़ना नहीं होगा।

public static void Run() { 
    var obj = new Remotable(); 
    var value = obj.field; 
    Console.WriteLine(value.ToString());  // No warning 
} 
+1

बहुत बहुत धन्यवाद। मुझे अभी यह चेतावनी मिली है, और यह भाग्यशाली था कि आपके यहां इसका जवाब था। –

+0

क्या आप 'var i = obj लिखना चाहते थे।खेत; Console.WriteLine (i.ToString()); '? –

0

यदि मार्शल ऑब्जेक्ट का दूसरा पक्ष मर गया है, तो यह एक रनटाइम त्रुटि फेंक देगा जिसमें कहा गया है कि संदर्भित वस्तु अब मौजूद नहीं है।

3

@ हंस-passant से सुझाव के अलावा, मुझे लगता है कि इस चेतावनी को ठीक करने के एक अन्य उपयोगी तरीका एक संपत्ति में अपने क्षेत्र बदल कर है।

public class Remotable : MarshalByRefObject { 
    public int field; 
} 

public class Remotable : MarshalByRefObject { 
    public int field { get; set } 
} 

बन सकता है और आपके पास कोई भी चेतावनी प्राप्त करें!

जाहिर है (हंस Passant पहले से ही इस के लिए एक उत्कृष्ट व्याख्या है, his post देखें), तो आप हमेशा वस्तु आप के साथ काम कर रहे हैं नहीं बदल सकते हैं (उदाहरण: WinForms जहां खेतों आपके लिए बनाए जाते) ताकि आप पर वापस आने की हो सकता है एक अस्थायी चर का उपयोग कर।

0

या आप लिख सकते हैं:

var obj = new Remotable(); 

Console.WriteLine(((int) obj.field).ToString());  // No warning 

यहाँ आप उस डाली (unboxing) के लिए अपनी खुद की जिम्मेदारी ले।

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