2012-02-24 9 views
6

निम्नलिखित संकलन त्रुटि का कारण क्यों है?"कक्षा ए: IX" से सामान्य "टी कहां टी: IX" की अनुमति क्यों नहीं है?

interface IX {} 
interface IY {} 
class XY : IX, IY {} 

void Foo<T>() where T : IX, IY 
{ 
    T xy = new XY(); 
    … // ^^^^^^^^ 
}  // error: "Implicit conversion of type 'XY' to 'T' is not possible." 

नोट: यदि class XY : IX और where T : IX एक ही त्रुटि तब आ जाएगा। हालांकि, मैं एक अधिक जटिल उदाहरण को चुना है क्योंकि एक सरल एक तरह के रूप में, circumventive जवाब उकसाया हो सकता है, "बस IX करने के लिए T से xy के प्रकार में परिवर्तन" जो का जवाब नहीं क्यों इस रूपांतरण विफल रहता है।

उत्तर

12

class ABC : IX, IY { } और Foo<ABC> दिए गए, तो क्या आप new XY() का उपयोग करने में सक्षम होने की उम्मीद करेंगे? क्योंकि आपको वह उम्मीद नहीं होनी चाहिए। कंपाइलर, या तो नहीं होगा।

टी हमेशा XY होने वाला नहीं है। टी एबीसी, डीईएफ, या कुछ और होने जा रहा है जो आपके दो इंटरफेस को कार्यान्वित कर सकता है और इसलिए आपके पास मौजूद बाधाओं को पूरा कर सकता है। एक्सवाई एबीसी, डीईएफ, या में टी के लिए असीमित संभावनाओं में से कोई भी परिवर्तनीय नहीं है, और इसलिए आपके पास आपका त्रुटि संदेश है: XY से T का निहित रूपांतरण संभव नहीं है।

क्या कानूनी है बस new T() होगा, और यह सच केवल अगर विधि इसे समर्थन करने के लिए विवश किया जाता है।

void Foo<T>() where T : IX, IY, new() 
{ 
    T obj = new T(); 
} 
+0

मैं बार बार तर्क में एक ही गलती को दोहरा रखना जब यह सामान्य प्रकार की कमी की बात आती है। आपके बहुत स्पष्ट स्पष्टीकरण के लिए धन्यवाद। – stakx

+5

@stakx: मुझे संदेह है कि आप गलत दिशा में तर्क कर रहे हैं। बाधा का मतलब है * कोई भी टी दिए गए इंटरफ़ेस प्रकार * में कनवर्टिबल है, नहीं * इस इंटरफ़ेस को लागू करने वाला कुछ भी टी * में परिवर्तनीय है। –

+0

@Eric, ठीक है! यदि आपको कोई फर्क नहीं पड़ता, तो क्या आप एक और संदेह की पुष्टि कर सकते हैं जो अभी मेरे लिए हुआ है? क्या भेद भी निम्नानुसार किया जा सकता है ... ** सही तर्क: ** 'टी' को 'फू' के कॉलर द्वारा चुना जाता है, न कि 'फू' द्वारा। यह 'टी' को सार्वभौमिक प्रकार बनाता है (कम से कम 'Foo' के लिए)। ** गलत तर्क ** (यानी मुझे, 3 घंटे पहले): 'टी 'को' फू 'द्वारा चुना जाता है, न कि उसके कॉलर द्वारा। यह इसे अस्तित्वहीन प्रकार बनाता है (कम से कम 'Foo' के कॉलर के लिए)। – stakx

15

क्योंकि है कि अगर कानूनी थे तो आप ऐसा कर सकते हैं:

interface IPet {} 
interface IMammal {} 
class Dog : IPet, IMammal {} 
class Cat : IPet, IMammal {} 
T Foo<T>() where T : IPet, IMammal 
{  
    return new Dog(); 
} 
... 
Cat cat = Foo<Cat>(); // Assigns a Dog to a variable of type Cat. 
+1

अच्छा उदाहरण! : डी –

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

  • कोई संबंधित समस्या नहीं^_^