2012-06-25 8 views
16

हम एक इस तरह सामान्य प्रकार पैरामीटर पर बाधा "से व्युत्पन्न" निर्दिष्ट कर सकते हैं:क्या "जहां से नहीं लिया गया" के लिए एक सामान्य प्रकार-बाधा है?

class Bar<T> where T : IFooGenerator 

वहाँ नहीं से प्राप्त निर्दिष्ट करने के लिए कोई तरीका है?


मेरे यूज-केस: मैं FooGenerator कि में चलाने योग्य हैं, प्रत्येक के लिए एक ही साथ में चलाना कोड के साथ का एक समूह है, लेकिन हम नहीं करते उन्हें हमेशा करना चाहते parallelized किया।

public class FooGenerator : IFooGenerator 
{ 
    public Foo GenerateFoo() { ... } 
} 

इस प्रकार, मैं समानांतर में फू पैदा करने के लिए एक सामान्य कंटेनर वर्ग बनाने के लिए:

public class ParallelFooGenerator<T> : IFooGenerator where T : IFooGenerator 
{ 
    public Foo GenerateFoo() 
    { 
     //Call T.GenerateFoo() a bunch in parallel 
    } 
} 

जब से मैं FooGenerator और ParallelFooGenerator<FooGenerator> चाहते विनिमेय हो सकता है, मैं ParallelFooGenerator : IFooGenerator बनाते हैं। हालांकि, मैं स्पष्ट रूप से ParallelFooGenerator<ParallelFooGenerator> कानूनी नहीं होना चाहता हूं।

तो, एक सहायक प्रश्न के रूप में, क्या यह संभवतः डिजाइन करने का एक बेहतर तरीका है यदि "बाधाओं से प्राप्त नहीं" असंभव हैं?

+2

'ParallelFooGenerator ' पहले से ही संभव नहीं है, क्योंकि 'ParallelFooGenerator' एक सामान्य प्रकार है और आप एक सामान्य तर्क निर्दिष्ट नहीं किया है। उदाहरण के लिए, 'समानांतर फ़ू जेनरेटर <समानांतर फ़ू जेनरेटर >' संभव है - और इस तरह के एक प्रकार को वास्तव में बुरा होने की इजाजत देगी? – cdhowie

+1

नहीं, यह संभव नहीं है - अनुमत बाधाएं: http://msdn.microsoft.com/en-us/library/d5x73970.aspx – Slugart

+0

@cdhowie: वाह, डरप, आप सही हैं। खैर, यह मेरी समस्या हल करता है :) लेकिन सवाल अभी भी दूसरों के लिए उपयोगी हो सकता है! –

उत्तर

9

आप निम्न की तरह कुछ इस्तेमाल कर सकते हैं:

public interface IFooGenerator 
{ 
    Foo GenerateFoo(); 
} 

interface ISerialFooGenerator : IFooGenerator { } 

interface IParallelFooGenerator : IFooGenerator { } 

public class FooGenerator : ISerialFooGenerator 
{ 
    public Foo GenerateFoo() 
    { 
     //TODO 
     return null; 
    } 
} 

public class ParallelFooGenerator<T> : IParallelFooGenerator 
    where T : ISerialFooGenerator, new() 
{ 
    public Foo GenerateFoo() 
    { 
     //TODO 
     return null; 
    } 
} 
+1

यह एक बेहतर डिजाइन imho है।* विरासत को एक स्तर नीचे प्रतिबंधित करने के बजाय एक इंटरफ़ेस को एक स्तर जोड़ना तरीका साफ करने वाला और समझने में आसान तरीका है। प्रत्येक इंटरफेस और कक्षा अपने आप को समझ में आता है। – vidstige

+0

@cdhowie * मेरी * समस्या हल हो गई है, लेकिन मैं इस सही को चिह्नित कर रहा हूं क्योंकि यह शीर्षक में प्रश्न का उत्तर देता है। धन्यवाद! –

7

ParallelFooGenerator<ParallelFooGenerator> पहले से ही संभव नहीं है, क्योंकि ParallelFooGenerator एक सामान्य प्रकार है और आपने सामान्य तर्क निर्दिष्ट नहीं किया है।

उदाहरण के लिए, ParallelFooGenerator<ParallelFooGenerator<SomeFooGenerator>> संभव है - और इस तरह के एक प्रकार को वास्तव में बुरा होने की अनुमति होगी?

4

सरल उत्तर नहीं है।

विस्तृत उत्तर है (अब भी कोई):

माइक्रोसॉफ्ट यह अच्छी तरह से कहते हैं उनके explanation of type constrains में: "संकलक कुछ गारंटी होनी चाहिए कि ऑपरेटर या विधि कॉल करने के लिए की जरूरत है किसी भी प्रकार के तर्क हो सकता है कि द्वारा समर्थन दिया जाएगा क्लाइंट कोड द्वारा निर्दिष्ट। "

बाधाओं का मौलिक उद्देश्य कुछ प्रकारों को इस्तेमाल होने से प्रतिबंधित नहीं करना है, बल्कि संकलक को यह जानने के लिए कि ऑपरेटरों या विधियों का समर्थन किस प्रकार किया जाता है। हालांकि, आप रन-टाइम पर check if a type implements/inherits a specific interface/base class कर सकते हैं और अपवाद फेंक सकते हैं। इसके साथ ही, आप इंटेलिजेंस से डिज़ाइन-टाइम त्रुटि प्राप्त नहीं कर पाएंगे।

मुझे आशा है कि इस मदद करता है।

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

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