2009-10-23 5 views
5

यहां मैं यह करना चाहता हूं:मैं अपने वांछित सी # polymorphism के साथ क्यों कॉम्पैक्ट नहीं कर सकता?

XmlWriter writer = XmlWriter.Create(
    (string.IsNullOrEmpty(outfile) ? Console.Out : outfile) 
); 

यह संकलित नहीं करता है, हालांकि, त्रुटि दे रहा है "सशर्त अभिव्यक्ति का प्रकार निर्धारित नहीं किया जा सकता है क्योंकि 'System.IO.TextWriter' और 'स्ट्रिंग' के बीच कोई अंतर्निहित रूपांतरण नहीं है ' "। उपरोक्त कोड निम्न का सरलीकरण है:

XmlWriter writer; 

if (string.IsNullOrEmpty(outfile)) 
{ 
    writer = XmlWriter.Create(Console.Out); // Constructor takes TextWriter 
} 
else 
{ 
    writer = XmlWriter.Create(outfile); // Constructor takes string 
} 

Create पर ये दो कॉल पूरी तरह मान्य हैं, और यह संकलित करता है। क्या यह और अधिक कॉम्पैक्ट बनाने का कोई तरीका है, जैसे कि मैं अपने इनलाइन परीक्षण के साथ करने की कोशिश कर रहा था?

यह मुझे समझ में नहीं आता है कि जो मैं चाहता हूं वह काम नहीं करता है। मानसिक रूप से इस बारे में सोचते हुए, ऐसा लगता है कि संकलक string.IsNullOrEmpty(outfile) का मूल्यांकन करेगा कि यह निर्धारित करने के लिए कि कौन सा मामला लेना है:

  • अगर स्थिति सत्य थी, तो यह Console.Out के साथ जाएगी, और फिर देखें कि इसे polymorphically संस्करण का चयन करना है XmlWriter.Create जो टेक्स्टवाइटर लेता है।
  • अगर स्थिति गलत थी, तो यह outfile के साथ जाएगी, और फिर देखें कि इसे XmlWriter.Create के संस्करण को polymorphically चुनने की आवश्यकता है जो एक स्ट्रिंग लेता है।

क्या एमएल में प्रोग्रामिंग ने मेरे दिमाग को तोड़ दिया है?

उत्तर

18

कारण आप ऐसा नहीं कर सकते है, क्योंकि संकलक जो संकलन समय पर उपयोग करने के लिए बनाने के लिए की अधिभार का चयन करना होगा - अपने दृष्टिकोण की आवश्यकता होगी यह क्रम में किया जाना चाहिए। कम से कम आप इसे कर सकते हैं शायद है:

XmlWriter writer = String.IsNullOrEmpty(outfile) 
    ? XmlWriter.Create(Console.Out) 
    : XmlWriter.Create(outfile); 
2

समस्या यह है कि आप संकलन समय क्या

(string.IsNullOrEmpty(outfile) ? Console.Out : outfile) 

लौटना चाहिए पर निर्धारित नहीं कर सकता है। क्या यह एक स्ट्रिंग होने जा रहा है या यह एक टेक्स्टवाइटर होने जा रहा है? यह केवल रन टाइम पर निर्धारित किया जा सकता है, इसलिए संकलन त्रुटि क्योंकि? संकलन समय पर ऑपरेटर को हल किया जाना है।

सबसे अच्छा आप इसे से बाहर निकल सकते शायद होगा:

XmlWriter writer = string.IsNullOrEmpty(outfile) 
    ? XmlWriter.Create(Console.Out) 
    : XmlWriter.Create(outfile); 
1

नहीं, आप दो अलग-अलग कॉल करने के लिए है के रूप में वे दो अलग-अलग निर्माता ये हैं।

कॉल करने के लिए संकलन समय पर निर्धारित किया जाता है ओवरलोड कौन सा है, तो आप अलग अलग भार के कॉल करने के लिए क्रम में एक डेटा प्रकार का चयन नहीं कर सकते।

इसके अलावा, सशर्त ऑपरेटर केवल एक ही डेटा प्रकार लौटा सकता है, आप इसे choise के आधार पर अलग-अलग डेटा प्रकारों को वापस नहीं कर सकते हैं।

3

सी # कंपाइलर संकलन के दौरान स्थिर रूप से निष्पादित करने के लिए एक विधि चुनता है। जब आप संकलित करते हैं तो उत्पन्न होने वाला आईएल एक विशिष्ट विधि का संदर्भ है। Polymorphism भाग रनटाइम पर आता है जब यह निष्पादित करने के लिए उस विशिष्ट कार्य के कार्यान्वयन का चयन करता है।

आपका? बयान कार्यावधि में और इस तरह के संकलक को समझ नहीं सकता कि कौन सी विधि निष्पादित करने के लिए के रूप में मूल्यांकन किया जाता है।

इसमें बदलें और यह काम करेगा।

XmlWriter writer = string.IsNullOrEmpty(outfile) ? 
    XmlWriter.Create(Console.Out) : 
    XmlWriter.Create(outfile); 
1

सी # स्थैतिक रूप से लिखा गया सभी बहुरूपता जादू समय संकलन हो रहा है। और आपकी सशर्त अभिव्यक्ति का प्रकार संकलन समय पर ज्ञात नहीं है।

+1

कंपाइलर संकलन समय पर कक्षा/विधि का नाम और तर्क चुनता है, लेकिन polymorphically रनटाइम पर कॉलवर्ट आईएल निर्देश के माध्यम से उस विधि के कार्यान्वयन को चुनता है। –

2

यहां कुछ चीजें हो रही हैं।

सबसे पहले, "अपवाद" टर्नरी ऑपरेटर (टीएम) के कारण होता है, न कि आप इसका उपयोग कहां कर रहे हैं। समस्या यह है क्योंकि आपके पास एक एकल अभिव्यक्ति है जो दो अलग-अलग प्रकारों को वापस करने की कोशिश कर रही है जिन्हें एकल, सामान्य आधार प्रकार (ऑब्जेक्ट के अलावा) में हल नहीं किया जा सकता है।

आगे, आपके कन्स्ट्रक्टर ओवरलोड शायद दो पूरी तरह से अलग-अलग प्रकार लेते हैं जो कि किसी भी तरह से संबंधित नहीं हैं। सी # कंपाइलर बहुत है, बहुत स्मार्ट, लेकिन यह नहीं है जो स्मार्ट है।

7

हर कोई निम्नलिखित सुझाव दे किया जा रहा है:

XmlWriter writer = String.IsNullOrEmpty(outfile) 
    ? XmlWriter.Create(Console.Out) 
    : XmlWriter.Create(outfile); 

बहरहाल, यह भी संभव है:

XmlWriter writer = XmlWriter.Create(string.IsNullOrEmpty(outfile) 
    ? Console.Out : new StreamWriter(outfile)); 

बाद IMO, अधिक कॉम्पैक्ट अपने मूल प्रयास के करीब है और,।

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

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