2010-01-29 12 views
9

के रूप में एक स्पष्ट कलाकार को पास करना मेरे पास एक कक्षा है जो अधिकतर बड़े सरणी और कुछ संबंधित हाउसकीपिंग के लिए एक रैपर है। मेरे पास एक ऐसा फ़ंक्शन है जो रेफ पैरामीटर लेता है। जब मैं फ़ंक्शन में कक्षा का उदाहरण पास करता हूं, तो मैं सरणी भेजना चाहता हूं।एक रेफ पैरामीटर (सी #)

मुझे स्पष्ट रूप से माना जाता है। मान लें कि मेरे पास कुछ फ़ंक्शन है जिसमें बाइट [] रेफ पैरामीटर है।

public void SomeFunction(ref byte[] someBytes); 

और मेरे पास एक ओवरलोडेड स्पष्ट कलाकार के साथ कुछ कक्षा है।

class SomeClass 
    { 
     byte[] someBytes; 
     public static explicit operator byte[](SomeClass someInstance) 
     { 
      return someInstance.someBytes; 
     } 
    } 

अब मैं एक पैरामीटर

SomeClass someInstance = new SomeClass(); 
    SomeFunction(ref (byte[]) someInstance); 

संकलक शिकायत "एक रेफरी या बाहर तर्क एक आबंटित चर होना चाहिए" के रूप में वर्ग के साथ समारोह कॉल करना चाहते हैं। मुझे यकीन नहीं है कि मैं संकलक को ठीक से मालिश करने में असफल रहा हूं या यदि आप वास्तव में ऐसा नहीं कर सकते हैं।

मैं एक संपत्ति या समारोह वापसी मान माना जाता है, लेकिन आप रेफरी द्वारा उन पारित नहीं हो सकता है (और अपने आप को शिक्षित करने के बाद मैं देख रहा हूँ क्यों ...)

मैं सरणी एक सार्वजनिक क्षेत्र बनाने के लिए नहीं करना चाहते हैं , लेकिन यह संकलक को संतुष्ट करता है। मैं लगता मैं बस के साथ सरणी संदर्भ के लिए एक स्थानीय चर बना सकते हैं, लेकिन इससे पहले और प्रत्येक समारोह कॉल के बाद कोड की एक अतिरिक्त पंक्ति है ...

संपादित करें: यह देखते हुए कि SomeFunction द्वारा लिखा गया था लायक हो सकता है एक तीसरी पार्टी और मुझे इसे बदलने की पहुंच नहीं है। इससे भी बदतर, मुझे नहीं लगता कि उनके पैरामीटर को वास्तव में रेफरी करने की जरूरत है ...

उत्तर

9

एक कास्ट एक असाइन करने योग्य चर नहीं है; आप अपने स्पष्ट कास्ट ऑपरेटर से रिटर्न वैल्यू पास कर रहे हैं।

आप एक रेफरी के रूप में यह पारित करने से पहले एक चर ठीक से डाली मूल्य पकड़े बना सकते हैं:

SomeClass someInstance = new SomeClass(); 
byte[] someBytes = (byte[])someInstance; 
SomeFunction(ref someBytes); 

ध्यान दें कि यह अब someBytes चर जो पुनर्निर्दिष्ट किया जा सकता है। पर कॉल करने के बाद आपको someInstance.someBytes पर कॉल करने के बाद आपको someInstance के आंतरिक मूल्य को फिर से सौंपने के लिए कार्रवाई करना होगा।

+0

तो यह पता चला है कि व्यावहारिक समाधान या तो एक सार्वजनिक क्षेत्र या एक छोटी विधि जिसका एकमात्र उद्देश्य में पारित करने के लिए कुछ स्थानीय चर के निर्माण को कवर करने के लिए है हो सकता है। मैं कुछ और खुदाई और जेनरिक मदद कर सकता है था भी – ajs410

+0

ठीक है, कुछ सरल अद्यतन करने के लिए एक साधारण सेटर पर्याप्त होगा। एक विकल्प के रूप में, आप एक इंटरफ़ेस बना सकते हैं कि कुछ फ़ंक्शन एक तर्क के रूप में लेता है और कुछ इंस्टेंस लागू करता है, और उस इंटरफ़ेस के माध्यम से अपने तर्क को कार्यान्वित करता है। –

1

आप ऐसा नहीं कर सकते हैं, आपको अपनी ऑब्जेक्ट को पहले एक चर में कास्टिंग करने के परिणाम को पूरा करने की आवश्यकता है।

, निम्नलिखित कोड पर विचार करें, तो क्या आप के लिए पूछ अनुमति दी गई थी:

public void SomeFunction(ref byte[] someBytes) 
{ 
    someBytes = new byte[] { 1, 2, 3 }; 
} 

SomeClass someInstance = new SomeClass(); 
SomeFunction(ref (byte[]) someInstance); 
// uh-oh, what is "someInstance" now? 

क्यों है तर्क चिह्नित "रेफरी", क्या समस्या यह है कि आप यहाँ हल करने की कोशिश कर रहे हैं?

+0

तर्क को संभावित रूप से चिह्नित किया गया है क्योंकि मूल तृतीय-पक्ष डेवलपर .NET को C++ लाइब्रेरी पोर्ट कर रहा था। जिस समस्या को मैं हल करने की कोशिश कर रहा हूं वह कुछ क्षेत्रों को सार्वजनिक क्षेत्र बनाने या स्थानीय चर बनाने के बिना रेफरी के आसपास नृत्य कर रहा है। मैंने "स्पष्ट कलाकार" चुना क्योंकि मुझे पता था कि हाउसकीपिंग फ़ील्ड खो जाएंगे। मैं उम्मीद कर रहा था कि कुछ इंस्टेंस कुछ फ़ंक्शन के साथ कुछ बाइट्स के संदर्भ को पास कर देगा। सार्वजनिक क्षेत्र का उपयोग करने से बहुत अलग नहीं है, लेकिन स्पष्ट जानवरों को मजबूर करने से यह दुरुपयोग के लिए कम प्रवण हो जाएगा। – ajs410

+1

ठीक है, "रेफरी" और "आउट" पैरामीटर को बैकिंग वैरिएबल की आवश्यकता होती है, वास्तव में इसके आसपास कोई रास्ता नहीं है, इसलिए आपको वैरिएबल को परिभाषित करना होगा जैसा कि आप पहले ही पा चुके हैं। आप निश्चित रूप से अपने लिए उस अनुवाद को करने के लिए स्वयं की कक्षा में शिम-विधियां बना सकते हैं, और इसके बजाय उन विधियों को कॉल कर सकते हैं, जो बदले में कास्ट करते हैं, एक चर में स्टोर करते हैं, और वास्तविक तरीकों को कॉल करते हैं, लेकिन हो सकता है कि या तो एक अच्छा समाधान नहीं है। –

+0

अंतिम समाधान में वास्तव में बाइट [] के संदर्भ की एक स्थानीय प्रतिलिपि बनाना शामिल है और उस स्थानीय प्रति को फिर से भरना शामिल है। यह तकनीकी रूप से रेफरी के बिंदु का उल्लंघन कर रहा है, लेकिन मुझे पूरा यकीन है कि तीसरे पक्ष के प्रोग्रामर को लगता है कि सी # में रेफरी सी ++ के समान थी और यह सच नहीं है। – ajs410

1

सी # में रेफ पैरामीटर के रूप में उपयोग किए जाने वाले मानों का दायरा सीएलआर की अनुमति से सीमित है। यह खंड 12.4.1.5.2 और 12.1.6 पर सीएलआई स्पेक में निर्दिष्ट है।1 और वर्तमान पद्धति

  • स्थानीय एक वस्तु की चर
  • सदस्य फील्ड
  • स्टेटिक फील्ड
  • सरणी तत्व
  • एक डाली से किसी से मेल नहीं खाती की

    • तर्क भी शामिल है इन और इसलिए ref मूल्य के रूप में उपयोग नहीं किया जा सकता है। संदर्भ द्वारा इसे पारित करने से पहले आपको इसे स्थानीय जैसे मूल्य पर असाइन करना होगा।

    +0

    spec के संदर्भ के लिए धन्यवाद! मैं थोड़ी देर के लिए सी # में नहीं आया, इसलिए एक तरह से यह एक अकादमिक सवाल था क्योंकि मैं पूरी तरह से भाषा की विभिन्न विशेषताओं का पता लगाता हूं ... और वहां निश्चित रूप से उनमें से बहुत सारे हैं। – ajs410

    0

    क्या आपको वास्तव में रेफ पैरामीटर डालना है? मेरे मामले में ऐसा कुछ ठीक काम करता है।

    byte[] someInstance = (byte[])new SomeClass(); 
    SomeFunction(ref someInstance); 
    
    संबंधित मुद्दे