2013-07-14 3 views
6

इंटरफ़ेस (I) एक संदर्भ प्रकार है, संरचना (एस) एक मान प्रकार है। स्ट्रक्चर इंटरफेस को कार्यान्वित कर सकते हैं।इंटरफ़ेस मान के रूप में संरचना मान पास करते समय मैं मुक्केबाजी से कैसे बच सकता हूं?

public interface I {} 
struct S: I {} 

मान लें कि एस का एक मूल्य है जो विधि के रूप में एक विधि के रूप में पारित किया गया है। इस मामले में इसे बॉक्स किया जाना चाहिए।

void Method(I i) {} 

void Test() { 
    var s = new S(); 
    this.Method(s); // <---- boxing! 
} 

क्या इस मामले में मुक्केबाजी से बचने का कोई तरीका है?

+1

एक संभावित साक्षात्कार प्रश्न की तरह लगता है के लिए ... मुझे याद है कि एक –

उत्तर

14

यदि आप के लिए Method की परिभाषा बदल आप मुक्केबाजी बच सकते हैं:

void Method<T>(T i) where T : I 
{ 
} 

यह मुक्केबाजी से बचा जाता है, क्योंकि कार्यावधि में CLR सामान्य तर्क (रों) के प्रकार के आधार सामान्य तरीकों माहिर हैं। संदर्भ प्रकार सभी एक ही कार्यान्वयन साझा कर सकते हैं, जबकि संरचना प्रकारों को प्रत्येक का अपना संस्करण मिलता है। इसका मतलब है Method में सभी परिचालन जो T पर निर्भर करते हैं, कंक्रीट संरचना प्रकार के आकार को ध्यान में रखेंगे।

आपको सावधान हालांकि, आभासी तरीकों System.ObjectEquals या GetHashCode की तरह पर परिभाषित i कारण होगा बुला आभासी विधि प्रेषण के बाद बॉक्सिंग किए जाने के बाद से किया जाना चाहिए, हालांकि JIT कुछ में स्थिर प्रेषण करने में सक्षम हो सकता है एक विधि तालिका सूचक की आवश्यकता है (मामले)। हालांकि, यदि आपका स्ट्रक्चर प्रकार वर्चुअल विधि को प्रश्न में ओवरराइड करता है, तो मुक्केबाजी को करने की आवश्यकता नहीं होगी, क्योंकि कॉल करने की विधि को फिर से स्थिर माना जाता है क्योंकि structs (और इसलिए उनके सदस्यों) को सील कर दिया जाता है।

आमतौर पर आप सीधे T आगे बाधित IEquatable<T> लागू करने के लिए और जैसे तुलना के लिए एक IEqualityComparer<T> का उपयोग करके Equals या GetHashCode बुला से बच सकते हैं

void Method<T>(T i) where T : I, IEquatable<T> 
{ 
    T other = ... 
    if(i.Equals(other)) //avoids boxing 
    { 
    } 
} 
+0

आप स्पष्ट रूप से क्यों यह काम करता है व्याख्या कर सकते हैं की कोशिश करेंगे? –

+0

क्या आप संरचना बाधा भूल गए थे? जहां टी: संरचना, I –

+0

@BradRem: यदि आप इसे पार करते समय संकलित समय पर अपना प्रकार जानते हैं, तो सी # प्रकार अनुमान कैप्चर करेगा और यह 'विधि (ओं) को कॉल करने जैसा होगा; इस बिंदु पर यह पहचाना जाता है कि आप एक संरचना का उपयोग कर रहे हैं और मुक्केबाजी से बचेंगे। संपादित करें: हालांकि, यदि आप संकलन समय पर 's' के प्रकार को नहीं जानते हैं (यानी, आपने इसे केवल इंटरफ़ेस के रूप में टाइप किया है, तो मैं लिख रहा हूं: 'मैं = नया एस()') फिर भी यह अभी भी होगा बॉक्स किया जाना चाहिए। (बेशक, उस बिंदु पर यह _already_ बॉक्स किया गया है, इसलिए वास्तव में बहुत कुछ नहीं करते हैं) –

0

उपयोग जेनरिक:

public interface I {} 
pubic struct S : I {} 
public class Foo 
{ 
    public static void Bar<T>(T i) 
     where T : I 
    {} 
} 
संबंधित मुद्दे

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