2010-10-04 23 views
6

मैं वस्तुओं के लिए कुछ विस्तार तरीकों, जो मैं प्रयोग की जाने वाली/वस्तुओं जो IEnumerable लागू करता है के लिए IntelliSense में दिखाया गया है नहीं करना चाहती विकसित किया है। संकल्पनात्मक रूप से मुझे कुछएक प्रकार पैरामीटर निर्दिष्ट करने के लिए जो किसी विशेष इंटरफ़ेस को लागू नहीं करता है?

public static T SomeMethod<T>(this object value) where T != IEnumerable 
     { 

     } 

क्या सी # में किसी भी प्रकार की बाधा को लागू करना संभव है?

संपादित करें

क्षमा करें, मैंने सवाल गलत तरीके से रखा है। मुझे सी # में स्वीकार्य बाधाओं को पता है, मैं क्या जानना चाहता हूं कि अगर इसे पूरा करने का कोई और तरीका है?

+0

आपके पास सी # में जेनेरिक पर चार प्रकार की बाधाएं हैं, और यह उनमें से एक नहीं है। मुझे नहीं लगता कि यह संभव है, लेकिन मेरे से अधिक अनुभव वाले किसी को इसकी पुष्टि करनी चाहिए। –

+0

इंटेलिसेन्स के साथ, मुझे लगता है कि आप यह टिप्पणी लिखने के लिए सबसे अच्छा कर सकते हैं कि यह विधि IENumerable को लागू करने वाले प्रकारों के लिए उपलब्ध नहीं है। यह सही नहीं है, लेकिन कुछ भी नहीं है। –

उत्तर

13

बस ओविंद की टिप्पणी की पुष्टि करने के लिए: सी # में ऐसी कोई बाधा नहीं है। बाधा के केवल प्रकार हैं:

  • where T : struct (गैर-व्यर्थ मान प्रकार बाधा)
  • where T : class (संदर्भ प्रकार बाधा)
  • where T : SomeClassName (एक विशेष वर्ग बाधा के लिए रूपांतरण)
  • where T : ISomeInterfaceName (रूपांतरण के लिए एक विशेष इंटरफ़ेस बाधा)
  • where T : U (किसी अन्य प्रकार के पैरामीटर बाधा में रूपांतरण)
  • where T : new() (parameterless निर्माता बाधा)

ध्यान दें कि मैं केवल विशिष्ट वर्ग और इंटरफ़ेस की कमी को अलग कर लिया है पूर्व के रूप में एक प्राथमिक बाधा है और बाद में एक माध्यमिक बाधा है।

+0

क्या इसे पूरा करने के लिए कोई अन्य शॉर्टकट तरीका है? –

+2

@ अनन्द्य: संकलन-समय, संक्षिप्त या लंबे समय तक ऐसा करने का कोई तरीका नहीं है। आप निष्पादन समय पर अपवाद फेंक सकते हैं, लेकिन ऐसा करने के लिए यह बहुत बुरा है। –

+1

वास्तव में बहुत बुरा :) और यह इंटेलिसेन्स से एक्सटेंशन विधि को हटाने के अपने लक्ष्य की सहायता नहीं करेगा। –

1

यह समर्थित नहीं है। कानूनी बाधाएं here सूचीबद्ध हैं।

0

दूसरों के रूप में उल्लेख किया है कि आप क्या करना काम करने के लिए नहीं जा रहा है चाहता हूँ, लेकिन, तुम क्या प्रकार की वस्तुओं की आप का समर्थन करना चाहते को देखो और कुछ वर्ग/इंटरफेस वे आम में है कि करने के लिए इसे सीमित कर सकते हैं, या आप कर सकते हैं केवल सामान्य भाग को कुचलने और कई एक्सटेंशन विधियों को लिखने की आवश्यकता है, ताकि आप IENumerable को अस्वीकार कर सकें।

0

आप नहीं कर सकते हैं, और मैं मानता हूं कि यह एक उपद्रव है, हालांकि जो मैंने खुद को खोजा है वह उतना ही नहीं है जितना आप खोज रहे हैं, क्योंकि बाधा के आधार पर ओवरराइडिंग (ताकि मैं ऐसा कर सकूं कक्षा और एक ही विधि या वर्ग का एक संरचना संस्करण, और उपयुक्त के रूप में लागू उपयुक्त है)।

दो मामलों में जहां हम अच्छी तरह से प्राप्त कर सकते हैं कर रहे हैं। जहां प्रयोग की जाने वाली एक विस्तार विधि नहीं चाहते के लिए हमारे कारण यह है कि यह पहले से ही एक उदाहरण विधि के रूप में आपूर्ति की है

एक है। वास्तव में हम इसे मुफ्त में प्राप्त करते हैं; उदाहरण विधियों का उपयोग हमेशा एक्सटेंशन विधियों के बजाय किया जाता है (हालांकि derivedClass.method() wont 'का उपयोग तब किया जाता है जब आप baseClass.method() पर कॉल करते हैं यदि यह केवल derivedClass में मौजूद है)।

अन्य मामले क्रम चयन है:

public static T SomeMethod<T>(this object value) where T != IEnumerable 
{ 
    if(typeof(T).GetInterface("IEnumerable") != null) 
    { 
    //behaviour appropriate for IEnumerable 
    } 
    else 
    { 
    //other behaviour. 
    } 
} 

यह आदर्श नहीं है, खासकर अगर केवल "IEnumerable के लिए व्यवहार उचित" एक अपवाद फेंकने के लिए है, लेकिन यह कभी कभी पर्याप्त हो सकता है।

+0

टाइपऑफ (टी) के साथ क्या हो रहा है। .GetInterface ("IENumerable")! = शून्य। क्या है या अधिक स्पष्ट नहीं है? –

+0

@ एस्बेन, किसी और चीज पर मेरी सोच से उधार लिया, जहां मुझे वस्तु से अलग प्रकार से निपटना पड़ा। हां, 'ठीक है' के रूप में ठीक है और बहुत स्पष्ट हो जाएगा। –

0

आप इस तरह कुछ कर सकते हैं, लेकिन केवल आपके द्वारा नियंत्रित किए जाने वाले प्रकारों के लिए।

आप इस तरह एक विधि करना चाहते हैं कहते हैं:

public static class XmlSerializableExtension { 
    public static string ToXml(this object self) { 
    // ... 
    } 
} 

लेकिन आप इसके साथ हर वस्तु, केवल अपनी कक्षाओं के एक सबसेट को प्रदूषित करने के लिए नहीं करना चाहती।

आप इस तरह इसे प्राप्त कर सकते हैं: अब

public interface MXmlSerializable { } 
public static class XmlSerializable { 
    public static string ToXml(this MXmlSerializable self) { 
    // ... 
    } 
} 

, आप वर्गों है कि आप इस विधि का "mixin" इंटरफेस के साथ लागू करना चाहते हैं चिह्नित:

public class MyClass : MXmlSerializable { 
    // ... 
} 

और यह केवल में दिखाई देगा इन वर्गों के लिए इंटेलिजेंस।

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

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