यदि आप किसी इंटरफ़ेस के नीचे कुछ गुजर रहे हैं, तो यहां तक कि यदि आपके पास इंटरफ़ेस को लागू करने वाला मान प्रकार है तो यह बॉक्सिंग हो जाएगा इंटरफ़ेस और संदर्भ प्रकार की तरह व्यवहार करें (क्योंकि इसे किसी संदर्भ प्रकार के अंदर बॉक्स किया गया है)।
interface IFoo {
int Value { get; set; }
}
struct Foo : IFoo {
public int Value { get; set; }
}
प्रभाव जब एक मान प्रकार के रूप में इस्तेमाल का निरीक्षण करें:
var a = new Foo() { Value = 3 };
var b = a; // copies value
b.Value = 4;
Console.WriteLine("a has {0}", a.Value); //output: a has 3
Console.WriteLine("b has {0}", b.Value); //output: b has 4
अब देखो क्या जब आप इसे इंटरफ़ेस करने के लिए डाली होता है:
var a = new Foo() { Value = 3 } as IFoo; //boxed
var b = a; // copies reference
b.Value = 4;
Console.WriteLine("a has {0}", a.Value); //output: a has 4
Console.WriteLine("b has {0}", b.Value); //output: b has 4
तो यह है कि क्या कोई फर्क नहीं पड़ता एक संरचना या वर्ग इंटरफ़ेस लागू करता है। यदि इंटरफ़ेस में डाला जाता है और फिर इंटरफ़ेस के नीचे पारित किया जाता है, तो यह संदर्भ प्रकार के रूप में व्यवहार करेगा।
संपादित: तो इन अपनी आवश्यकताओं कर रहे हैं ...
अनुबंध एक्स के लिए:
- अगर एक struct/लागू करता है एक संकलन त्रुटि फेंक सकता है विरासत में एक्स
- एक्स एक अमूर्त वर्ग नहीं है।
ठीक है, तो आप बस अटक जाते हैं, क्योंकि वे एक-दूसरे से विरोधाभास करते हैं।
- यदि संकलन लागू होता है/अनुबंध प्राप्त होता है तो संकलन त्रुटि प्राप्त करने का एकमात्र तरीका यह है कि यह एक सार वर्ग है।
- चूंकि आप विरासत विकल्पों को खोलने के लिए एक अमूर्त वर्ग का उपयोग नहीं कर सकते हैं, तो आपको एक इंटरफ़ेस का उपयोग करना होगा।
- नियम लागू करने का एकमात्र तरीका है कि एक स्ट्रक्चर इंटरफ़ेस को कार्यान्वित नहीं कर सकता है, रन-टाइम के दौरान होगा।
बाधा where T: class, IFoo
का उपयोग हर समय भी काम नहीं करेगा। (समान Foo
और IFoo
ऊपर के आधार पर) अगर मैं इस विधि था:
static void DoSomething<T>(T foo) where T: class, IFoo {
foo.Value += 1;
Console.WriteLine("foo has {0}", foo.Value);
}
तो यह इस परिस्थिति में एक संकलन त्रुटि फेंक होगा:
var a = new Foo(){ Value = 3 };
DoSomething(a);
लेकिन यह इस परिस्थिति में ठीक काम करेगा :
var a = new Foo(){ Value = 3} as IFoo; //boxed
DoSomething(a);
तो जहाँ तक मेरा सवाल है, where T: class, IFoo
शैली बाधा का उपयोग करें, और तब यह कोई बात नहीं हो सकता है अगर एक struct कार्यान्वयन इंटरफ़ेस को जब तक यह बॉक्स किया गया हो। एक बॉक्सिंग संरचना पारित होने पर ईएफ की जांच करने पर निर्भर करता है। शायद यह काम करेगा।
यह काम नहीं करता है, तो कम से कम सामान्य बाधा आप हिस्सा तरह से वहाँ हो जाता है, और आप जाँच कर सकते हैं foo.GetType().IsValueType
(ऊपर मेरी DoSomething
विधि की चर्चा करते हुए) और बॉक्सिंग structs के मामले को संभालने के लिए एक ArgumentException
फेंक देते हैं।
ऐसा लगता है कि प्रकार एक कार्यान्वयन विस्तार होगा, जो इंटरफ़ेस पहली जगह में सारण करने का प्रयास करता है। मैं उत्सुक हूँ; आप केवल संदर्भ प्रकार कार्यान्वयन की अनुमति क्यों देना चाहते हैं? –
मुझे नहीं लगता कि ऐसा करने का कोई तरीका है, लेकिन क्या वास्तव में यह है कि आपके 'उपयोग प्रकार <>' वर्ग (एसएस) पर अतिरिक्त 'कहां' खंड जोड़ने के लिए और अधिक काम है? – Cameron
@Ed: मेरे विशिष्ट मामले में, मेरे पास एक इंटरफ़ेस 'आईईएनटीटीआई' है जिसे मैंने अपनी सभी व्यावसायिक संस्थाओं को लागू करने दिया। इकाई फ्रेमवर्क मांग करता है कि सभी इकाई प्रकार संदर्भ प्रकार हैं, इसलिए ईएफ के साथ सभी इंटरैक्शन के लिए यह आवश्यक है। चूंकि मुझे पता है कि मैं किसी भी इकाई प्रकार नहीं चाहता जो संदर्भ प्रकार नहीं हैं, मैं पहले से ही इंटरफ़ेस पर निर्दिष्ट करना चाहता हूं। –