2012-07-06 11 views
8

मैंने नीचे दिए गए कोड में अपनी समस्या को सरल और पुन: उत्पन्न किया है। मुझे जो त्रुटि मिल रही है वह है: तर्क 1: 'System.Collections.ObjectModel.Collection' से 'System.Collections.ObjectModel.Collectionसी # इंटरफेस के संग्रह के रूप में संग्रह को पास करना

डिज़ाइन निर्णयों के लिए कुछ पृष्ठभूमि जो इस समस्या का कारण बनती हैं: मेरे पास है "आईफ्रूट" से निपटने के लिए एक वेब सेवा बनाई, लेकिन एसओएपी और एंडपॉइंट बाइंडिंग की प्रकृति के कारण मैं उन्हें समझता हूं मैंने आईफ्रूट के स्पष्ट कार्यान्वयन के साथ विधियां बनाई हैं। व्यापार परत पर, फल के प्रत्येक विशिष्ट कार्यान्वयन के लिए एक अलग विधि बनाने से पहले बहुत सारे डुप्लिकेट कोड का कारण बनता है, और दूसरी बात यह है कि वेब सेवा में नए आईफ्रूट प्रकारों को स्वीकार करने के बाद व्यापार और सेवा परत को कसकर पर्याप्त रूप से जोड़ा जाता है, इसके बाद भी मेरे कोड को बदलने की आवश्यकता होगी व्यापार परत में (अनावश्यक कोड की एक और प्रति जोड़ना)। यह डिज़ाइन वह है जिसे मैंने अतीत में जावा का सफलतापूर्वक कार्यान्वित किया है, लेकिन सी # इंटरफेस मुझे फेंकने के लिए काफी अलग हैं। कृपया सलाह दें।

public interface IFruit{ 
    public string TakeBite(); 
} 

public Apple : IFruit{ 
    public string TakeBite(){ 
     return "tasty bite of apple"; 
    } 
} 

public void EatFruit(Collection<IFruit> fruits){ 
    foreach(var fruit in fruits){ 
     Console.WriteLine(fruit.TakeBite()); 
    } 
} 

public void EatApples(Collection<Apple> apples){ 
    this.EatFruit(apples); 
} 

उत्तर

9

अपने EatFruit विधि बदलने का प्रयास करें IEnumerable<IFruit>

public void EatFruit(IEnumerable<IFruit> fruits) 
{ 
    foreach (var fruit in fruits) 
    { 
     Console.WriteLine(fruit.TakeBite()); 
    } 
} 

इंटरफ़ेस IEnumerable<out T> का समर्थन करता है सहप्रसरण को स्वीकार करने के बाद से यह out संशोधक के साथ चिह्नित है। Collection<T> इस तरह के एक संशोधक के साथ चिह्नित नहीं है।

+0

धन्यवाद। यह संकलित करता है।अब मेरे यूनिट परीक्षणों को अपडेट करने के लिए। – YouGotCSharpInMyJava

1

इसे कॉन्वर्सिस कहा जाता है।
हालांकि, यह परिवर्तनीय संग्रह के साथ संभव नहीं है।

अन्यथा, EatFruit

fruits.Add(new Orange()); 

नेट 4, के लिए reas-केवल इंटरफेस सहप्रसरण का समर्थन करता है, तो आप इसे IEnumerable<IFruit> को बदल सकते हैं और यह काम करेंगे लिख सकते हैं।

+0

ऑर्रेट उपकरण IFruit मानते हैं तो क्या वहां कोई समस्या है? – Charleh

+1

@ चार्लेह: 'फल' _actually_ 'संग्रह ' है। यह 'ऑरेंज' नहीं रख सकता है। – SLaks

+0

मैंने सोचा था कि फल एक संग्रह था जिसमें यह किसी भी प्रकार का हो सकता है जो IFruit लागू करता है? – Charleh

0

IEnumerable का उपयोग कर आप टाइप कर सकते हैं संग्रह की जाँच (बिट भयंकर लेकिन यह काम करना चाहिए) के अलावा:

public void EatApples(Collection<IFruit> fruit) 
    var col = new Collection<IFruit>(); 

    fruit.Where(x => x is Apple).ToList().ForEach(x => col.Add(x)); 

    this.EatFruit(col); 
} 

हालांकि मैं IEnumerable के बजाय का उपयोग करें - यह अगर तुम refactor नहीं कर सकते सिर्फ एक विकल्प है: पी

(यह प्रकार के रूप में है सुरक्षित आप इसे बनाने के रूप में!)

+0

यह 2x काम करेगा - एक सूची बनाएं फिर प्रत्येक संग्रह में जोड़ें। बेहतर करने के लिए: 'foreach (फल में var x.OfType ()) {col.Add (x); } '। –

+0

हाँ सच - कहीं भी मैंने यह नहीं कहा कि यह प्रदर्शनकारी होगा (और मैंने वहां भी डरावना उल्लेख किया था!): डी – Charleh

0

सरल समाधान:

public void EatApples(Collection<Apple> apples){ 
    this.EatFruit(
      new Collection<IFruit>(
       apples.Cast<IFruit>() 
     ) 
    ); 
} 

बेहतर समाधान: C# 4 में पेश किए गए कॉन्वर्सिस का उपयोग करें: देखें केविन का उत्तर

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