2016-02-04 10 views
6

मैं डीटीओ की सूची में चयन करके एक डीटीओ से व्यूमोडल्स की एक सूची बनाने की कोशिश कर रहा हूं।संकलक इस चुनिंदा कॉल के प्रकार का अनुमान क्यों नहीं लगा सकता?

विधि के लिए प्रकार तर्क के उपयोग से नहीं लगाया जा सकता प्रकार तर्क

मेरा प्रश्न क्यों नहीं कर सकते हैं, है निर्दिष्ट करने का प्रयास: हालांकि, संकलक मुझे एक त्रुटि कहावत देता है? TextSectionDTO और ImageSectionDTO दोनों SectionDTO से व्युत्पन्न हैं। मैं के List बनाने की कोशिश कर रहा हूं, और TextSection और ImageSection दोनों Section से व्युत्पन्न हैं।

मुझे पता है कि यह प्रश्न यहां पोस्ट किए गए कुछ अन्य प्रश्नों के करीब है, लेकिन मुझे वहां कोई जवाब नहीं मिला।

private List<Section> BuildSectionViewModel(IEnumerable<SectionDTO> ss) 
{ 
    var viewModels = ss.Select((SectionDTO s) => 
    { 
     switch (s.SectionType) 
     { 
      case Enums.SectionTypes.OnlyText: 
       return new TextSection((TextSectionDTO) s); 
      case Enums.SectionTypes.OnlyImage: 
       return new ImageSection((ImageSectionDTO) s); 
      default: 
       throw new Exception("This section does not exist - FIXME"); 
     } 
    }).ToList(); 

    return viewModels; 
} 

जब मैं प्रकार बदल सकते हैं कि मैं केवल सुपर क्लास SectionDTO स्वीकार करते हैं और केवल वापसी धारा (मैं उन दोनों को सामान्य वर्गों इस परिदृश्य में कर) आप की तरह का चयन काम करता था:

यह मेरा कोड है उम्मीद करते हैं। फिर जब मैं प्रकारों को केवल टेक्स्टसेक्शन डीटीओ और टेक्स्टसेक्शन में बदलता हूं (सार तत्वों को वापस बदल रहा हूं), तो चयन अब और काम नहीं करता है।

मुझे एक समाधान चाहिए ताकि मैं इसे अभी निर्माण के साथ काम करने के लिए प्राप्त कर सकूं, हालांकि मुझे इसमें अधिक दिलचस्पी है कि यह इस तरह से क्यों काम नहीं करता है। यहां तक ​​कि अगर मैं इसे काम करने के लिए प्राप्त कर सकता हूं तो भी मैं इसे बाद में पुनः प्रतिक्रिया दूंगा।

नोट:

  • मैं लक्षित कर रहा MVC 4.5 (ताकि संकलक अनुमान लगाने के लिए है, जो यहां पर कुछ इसी तरह के सवाल का हल था सक्षम नहीं होने के कुछ पुराने संस्करण नहीं है)।
  • स्विच क्लॉज में एक डिफ़ॉल्ट मामला है, यानी त्रुटि किसी मान को वापस न करने वाले पथ के कारण नहीं होनी चाहिए।

उत्तर

6
case Enums.SectionTypes.OnlyText: 
    return new TextSection((TextSectionDTO) s); 
case Enums.SectionTypes.OnlyImage: 
    return new ImageSection((ImageSectionDTO) s); 

इन दोनों मामलों एडवेंचर्स प्रकार लौट आते हैं। अगर उन प्रकार के एक ही आधार प्रकार से निकाले जाते हैं संकलक बहुत चालाक isn't जाँच करने के लिए ताकि आप उन्हें स्पष्ट रूप कास्ट करने के लिए है:

case Enums.SectionTypes.OnlyText: 
    return (SectionDTO) new TextSection((TextSectionDTO) s); 
case Enums.SectionTypes.OnlyImage: 
    return (SectionDTO) new ImageSection((ImageSectionDTO) s); 

क्यों इस isn't संकलक पर लागू किया? मुझे लगता है कि ऐसा इसलिए है क्योंकि संकलक को कई अलग-अलग प्रकार की जांच करनी पड़ती है। मान लें कि आपके दो प्रकार Foo1 और Foo2 सीधे Bar से प्राप्त नहीं होते हैं, लेकिन दो अलग-अलग (Bar1 और Bar2 तदनुसार) कि स्वयं Bar से प्राप्त होते हैं। अब संकलक को जांचना चाहिए कि Foo1 और Foo2 किसी भी सामान्य बेस-क्लास को असाइन किया जा सकता है, जिसे वे नहीं कर सकते हैं, और यह भी जांच सकते हैं कि वे किसी सामान्य बेस-क्लास (Bar) से प्राप्त होते हैं या नहीं। अंत में हमें object तक पूरी विरासत-श्रृंखला की जांच करनी पड़ी, किसी भी इंटरफेस का उल्लेख नहीं किया जाना चाहिए जिसे जांचना चाहिए। TSource और TResult -

class Foo1 : Bar1 {} 
class Foo2 : Bar2 {} 

class Bar1 : Bar {} 
class Bar2 : Bar {} 
+0

ठीक समाधान हो जाना चाहिए, इस काम किया, दोनों रिटर्न के पीछे 'धारा' के रूप में चिपकाया। मुझे ऐसा करने की ज़रूरत क्यों है? क्या यह तथ्य नहीं होना चाहिए कि वे दोनों धारा से निकलते हैं, इस तथ्य को देखते हुए कि मैं अभिव्यक्ति की विधि में अनुभागों की एक सूची वापस कर रहा हूं? – Glubus

+1

मुझे लगता है कि ऐसा इसलिए है क्योंकि यदि संकलक पूरे विरासत-श्रृंखला की जांच करेगा तो यह पूरी श्रृंखला पर कई लूप ले सकता है। Assuem आप एक बहुत गहरी श्रृंखला होगी। अब संकलक को पूरे श्रृंखला में उल्लिखित सभी इंटरफेस और बेस-क्लास के खिलाफ जांच करनी चाहिए जो बहुत अधिक समय ले सकती है। – HimBromBeere

+1

वे दोनों 'ऑब्जेक्ट' से भी उत्तराधिकारी हैं। –

3

Select विधि दो प्रकार aguments है।चूंकि आप इसे IEnumerable<SectionDTO> पर आक्रमण कर रहे हैं, TSourceSectionDTO होने का अनुमान है, इसलिए ss.Select((SectionDTO s) => की आवश्यकता नहीं है और केवल ss.Select(s => ... हो सकती है।

समस्या TResult है जो आपके मामले में अनुमानित नहीं किया जा सकता है। क्यूं कर? आपके पास दो रिटर्न हैं - TextSection और ImageSection। वे समान नहीं हैं और उनमें से कोई भी दूसरे का आधार नहीं है। आपको क्या लगता है कि कंपाइलर का अनुमान लगाना चाहिए? आपको लगता है कि उत्तर सामान्य आधार प्रकार Section होना चाहिए, लेकिन यह एक सामान्य आधार object या दो प्रकार के किसी भी सामान्य बेस क्लास/इंटरफ़ेस पर लागू हो सकता है। दूसरे शब्दों में, परिणाम संदिग्ध है, इसलिए अनुमान लगाने के बजाय कि आपका इरादा क्या है, संकलक को आपको स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता है। त्रिगुट ऑपरेटर ? : की ही तरह यह सिर्फ एक शाखा में आम आधार को सिद्ध करने होगा तो निम्नलिखित यह

var viewModels = ss.Select(s => 
{ 
    switch (s.SectionType) 
    { 
     case Enums.SectionTypes.OnlyText: 
      return (Section)new TextSection((TextSectionDTO) s); 
     case Enums.SectionTypes.OnlyImage: 
      return new ImageSection((ImageSectionDTO) s); 
     default: 
      throw new Exception("This section does not exist - FIXME"); 
    } 
}).ToList(); 
+0

यह स्पष्टीकरण भी बहुत उपयोगी है, मैं इसे अब समझता हूं। धन्यवाद। – Glubus

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

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