2010-01-28 12 views
5

मान लीजिए आप निम्नलिखित वर्ग है पासिंग:एक अंतरफलक संग्रह

class Car : IPainting 
{ 
... 
} 

फिर इस तरह एक समारोह:

void AddCars(IEnumerable<Car> collection) 

फिर इस तरह एक कोड का टुकड़ा:

Car bmw = new Car(); 
Car mercedes = new Car(); 

IPainting a = (IPainting) bmw; 
IPainting b = (IPainting) mercedes; 

IPainting[] paintings = new IPainting[] {a, b}; 

AddCars(paintings); // fails to compile 

यह की पाठ्यक्रम संकलित नहीं करता है क्योंकि AddCars() विधि केवल कारों का संग्रह स्वीकार करती है लेकिन यह 'पेंटिंग्स' सरणी से बना है।

मुझे पता है कि सी # 4.0 शायद इसके लिए एक समाधान प्रदान करेगा। क्या इसके लिए आज कोई कामकाज है?

धन्यवाद,

अल्बर्टो

+1

सी # 4.0 एक प्रदान नहीं करेगा आपके पास यहां मौजूद कोड के लिए समाधान। आप विरासत में उच्चतर किसी प्रकार को पारित करने में सक्षम नहीं होंगे कुछ कम उम्मीद की एक विधि के लिए rarchy। जैसा कि अन्य ने बताया है, आपकी विधि को आईपैंटिंग में लेना होगा - इसके लिए काम करने के लिए कार नहीं। –

उत्तर

3

सी # 4 कोड है कि आप ने लिखा अनुमति नहीं दी जाएगी, विधि के बाद से AddCars एक IEnumerable<Car> जो IPainting लागू करता है उम्मीद है। इसका मतलब यह नहीं कि आप पास कर सकते हैं कि किसी भी वर्ग को लागू करने IPainting (आप उदाहरण के लिए एक class Bike : IPainting जो भी Car वर्ग के साथ कोई संबंध नहीं है कि हालांकि, यह दूसरी तरह के आसपास की अनुमति देगा हो सकता था;। यदि आप void AddCars(IEnumerable<IPainting> collection) है आप पास कर सकते हैं विधि करने के लिए एक List<Car>

तब तक, आप (जैसे painting.Cast<Car>() अन्य उत्तर में सुझाव दिया) विधि Car दृश्यों गुजर, कुछ कास्टिंग तंत्र का उपयोग करके करने के लिए छड़ी की जरूरत होगी।

+0

पेंटिंग्स है। कैस्ट () कुछ लूप के मुकाबले कुछ तेज है जो प्रत्येक ऑब्जेक्ट को कार प्रकार में डाल देता है? धन्यवाद। – abenci

+0

@devdept: नहीं कह सकता; उस पर कोई प्रदर्शन तुलना कभी नहीं की। आश्चर्य होगा कि यह वास्तविक दुनिया परिदृश्यों के लिए पर्याप्त तेज़ नहीं है। –

4

कैसे LINQ का उपयोग कर के बारे में: AddCars(paintings.Cast<Car>());

+0

हम लिंक का उपयोग नहीं करते हैं। हम डेटाबेस का बिल्कुल उपयोग नहीं करते हैं। आपके द्वारा सुझाए गए दृष्टिकोण पर मैं और कहां पढ़ सकता हूं? – abenci

+3

@devdept - यह वस्तुओं के लिए linq है, linq करने के लिए linq नहीं। इसमें डेटाबेस के साथ कुछ भी नहीं है। –

7

एक सामान्य विधि का उपयोग कर प्रयास करें:

void AddCars<T>(IEnumerable<T> collection) where T : IPainting 
+0

क्या यह समाधान कार [] और आईपैनटिंग [] सरणी को AddCars() में पारित करने की अनुमति देगा? – abenci

+0

हां, यह इसकी अनुमति देगा। –

4

आपका कोड मौलिक रूप से दोषपूर्ण है। आपकी कक्षा गारंटी देता है कि सभी कारें आईपैंटिंग लागू करती हैं लेकिन इस बात की कोई गारंटी नहीं है कि सभी आईपैंटिंग कारें हैं।

आप शायद इस काम को कुछ कास्टिंग के साथ बना सकते हैं लेकिन मुझे लगता है कि आपको अपने डिजाइन पर पुनर्विचार करना चाहिए।

AddCars(new Car[] { bmw, mercedes }); 
+0

आप सही हैं, लेकिन मुझे पता है कि यह हमेशा सच है। क्या इसे लागू करने का कोई तरीका है? एक कार ऑब्जेक्ट के साथ मैं इसे आसानी से आईपैंटिंग पर डाल सकता हूं, समस्या यह है कि मैं संग्रह के लिए ऐसा नहीं कर सकता। – abenci

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