2010-02-09 15 views
9

मुझे मिल गया एक वर्ग एक्स और एक वर्ग वाई, जिनमें से बाद एक्स से निकला है:सी # बहुरूपता सरल सवाल

class x {} 
class y : x {} 

तब कहीं मैं एक्स की एक सूची का उपयोग कर रहा:

List<X> lstX; 
... 

तब मैं उन पंक्तियों के साथ 'मेरे अन्य सूची में वाई की एक नई सूची का उपयोग करने के डेटा से चाहते हैं ... कुछ:

List<Y> lstY = lstX; 

मेरा मानना ​​है कि यह होगा कि एक्स wou की सूची में आइटम्स एलडी स्वचालित रूप से वाई में परिवर्तित हो जाता है, लेकिन यह मामला नहीं है।

इसके अलावा, मैं एक निश्चित एक्स से वाई का एक नया उदाहरण कैसे शुरू कर सकता हूं? मैं करना चाहता हूं:

var newX = new X(); 
var newY = new Y(X); 

लेकिन ऐसा लगता है कि ऐसा नहीं लगता है।

आपकी मदद के लिए धन्यवाद! और स्वरूपण के लिए खेद है, मेरे सबसे अच्छे

+0

संभावित डुप्लिकेट: http://stackoverflow.com/questions/2231593/upcasting-with-a-generic-type-parameter –

उत्तर

27

यहाँ सवाल के एक जोड़े हैं: आप आरंभ और मैन्युअल रूप से नया List<Y> पॉप्युलेट करने के लिए की जरूरत है।

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

क्योंकि तब ऐसा होता है:

IEnumerable<Tiger> tigers = new List<Tiger>(); 
IEnumerable<Animal> animals = tigers; 

यह कानूनी है, क्योंकि IEnumerable<T> कोई "जोड़ें" विधि है और इसलिए यह गारंटी है:

List<Tiger> tigers = new List<Tiger>(); 
List<Animal> animals = tigers; // this is illegal because if we allow it... 
animals.Add(new Giraffe()); // ... then you just put a giraffe into a list of tigers. 

सी # 4 में यह ऐसा करने के लिए कानूनी हो जाएगा सुरक्षित रहने के लिए।

सी # 4.

http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx

की इस नई सुविधा

दूसरा प्रश्न के बारे में जानकारी के लिए सहप्रसरण पर लेख की मेरी श्रृंखला देखें: "मैं कैसे टाइगर का एक नया उदाहरण प्रारंभ कर सकता है, एक निश्चित पशु से"

आप नहीं कर सकते। प्रश्न में पशु लेडीबग हो सकता है। लेडीबग के उदाहरण से आप एक नया टाइगर कैसे शुरू कर रहे हैं? इससे कोई मतलब नहीं आता है, इसलिए हम आपको ऐसा करने नहीं देते हैं। यदि आप अपनी खुद की विशेष विधि लिखना चाहते हैं जो जानता है कि मनमानी जानवरों को बाघों में कैसे बदलना है, तो आप ऐसा करने के लिए स्वतंत्र हैं। लेकिन हम नहीं जानते कि यह आपके लिए कैसे किया जाए।

+1

Dagnammit यह एक अच्छा जवाब है, मैं इसे बेहतर नहीं रख सका। वास्तव में, इसे साबित करने के लिए, मैंने नहीं किया। डर आप एरिक लिपर्ट। –

+0

वास्तव में उत्कृष्ट उत्तर, बहुत बहुत धन्यवाद। – ibiza

+0

हालांकि मेरे बाघों के समूह के साथ जानवरों की एक सूची को तत्काल करना, और फिर कुछ गिरफ़ेस जोड़ना मेरे लिए कानूनी लगता है, क्योंकि आपको वहां जानवरों की एक सूची मिली है। ऐसा होता है कि आपने इसे कुछ बाघों के साथ शुरू किया। यह मेरा तर्क होना चाहिए कि मुझे बदलना होगा। – ibiza

1

नहीं की कोशिश कर रहा है, क्योंकि आप यह सुनिश्चित करें कि प्रकार के 'एक्स' हैं जो listX में सभी आइटम,,
विरासत संबंध प्रकार Y के भी कर रहे हैं नहीं किया जा सकता अन्य तरीका है चारों ओर: प्रकार वाई के एक आइटम, एक्स के लिए casted जा सकता है क्योंकि वाई है-एक एक्स

सी # में, वहाँ भी कोई 'प्रतिलिपि कंस्ट्रक्टर्स C++ की तरह उपलब्ध हैं, इसलिए मुझे डर है कि तुम होगा उस तर्क को लागू करने के लिए, वाई के एक नए उदाहरण को शुरू करने में सक्षम होने के लिए, एक निश्चित एक्स से स्वयं। इसके अलावा, ध्यान रखें कि कक्षाएं संदर्भ प्रकार हैं ...

3

यह कभी भी काम नहीं करेगा; सभी List<Y> lstY = lstX; सिर्फ प्रतियां संदर्भ (जब तक आप अपनी स्वयं की सूची प्रकार के अपने खुद के निहित स्थिर रूपांतरण ऑपरेटर जोड़ने) के बाद - तो यह अभी भीX की एक सूची है और चीजों को अन्यY उदाहरणों से हो सकता है।

में भी 4.0, सह/विपरीत विचरण करने के लिए एक विस्तार नहीं करता है: सूची (दोनों in और out), या ख: ठोस प्रकार (List<T> की तरह)।

दिलचस्प बात यह है कि, (और हमेशा) संदर्भ प्रकारों के सरणी के लिए काम करेगा, लेकिन केवल X[] arrX = arrY; दिशा में काम करेगा। यह कुछ भी परिवर्तित नहीं करता है; यदि आप कोशिश करते हैं और गलत डेटा डालते हैं तो यह एक अपवाद फेंक देगा।

+0

यहां तक ​​कि काम नहीं करेगा, क्योंकि Y है एक एक्स, लेकिन एक्स एक वाई –

+0

@Frederik नहीं है - आह सही, हाँ। मेरी गलती। फिक्स्ड। –

0

आपका परिदृश्य सामान्य पॉलीमोर्फिक उपयोग मामलों से पीछे की तरफ है। वाई एक एक्स है, लेकिन एक्स एक वाई

कि मन आप बल यह तरीका कंस्ट्रक्टर्स और whatnot में क्लोनिंग कोड रखकर आप कहते हैं कि काम कर सकता था में साथ

नहीं है।

0

आपके पहले उदाहरण के साथ समस्या यह है कि वाई एक्स से निकला है, इसलिए यह "एक्स है", लेकिन "एक्स एक वाई नहीं है", सी # वर्तमान में इस विधि में टाइप कास्टिंग का समर्थन नहीं करता है । आप कास्ट के लिए एक्सटेंशन विधियों का उपयोग करने का प्रयास कर सकते हैं, जैसे कि lstX.ConvertAll इसे पूरा करने के लिए एक सहायक के रूप में।

दूसरा सवाल आप एक कॉपी निर्माता गौर करने के लिए, जैसे:

public Y(X baseObject) { 
    //copy all the data you need here... 
} 
1

यह नहीं स्वचालित रूप से X से Y "चौड़ा" कर सकते हैं वस्तुओं 'प्रकार, क्योंकि X Y नहीं है, लेकिन वाई एक्स

आप X से Y तक कास्टिंग की कोशिश कर सकते है, लेकिन यह एक InvalidCastException के साथ विफल करेंगे जब तक कि आपके वस्तु मूल रूप से एक वाई एक एक्स के रूप में मुखौटा धारण कर लिया सब साथ था।

IList<Y> yList = new List<Y>(); 
foreach (var x in xList) 
{ 
    var y = new Y(x); // Copies/clones inherited properties from x to a new Y 
    // TODO: Set other properties of y not present on x 
    yList.Add(y); 
} 
1

इस प्रयास करें:


using System.Collections.Generic; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List myList; 

      myList = GetMyList(MyListTypeEnum.MyList1); 
      myList = GetMyList(MyListTypeEnum.MyList2); 
     } 

     public static List GetMyList(MyListTypeEnum tipo) 
     { 
      List result; 
      result = new List(); 

      switch (tipo) 
      { 
       case MyListTypeEnum.MyList1: 
        List myList1 = GetMyList1(); 
        foreach (var item in myList1) 
        { 
         result.Add((IMyList) item); 
        } 
        break; 
       case MyListTypeEnum.MyList2: 
        List myList2 = GetMyList2(); 
        foreach (var item in myList2) 
        { 
         result.Add((IMyList) item); 
        } 
        break; 
      } 

      return result; 
     } 

     public static List GetMyList1() 
     { 
      List myList1 = new List(); 
      myList1.Add(new MyList1 { Code = 1 }); 
      myList1.Add(new MyList1 { Code = 2 }); 
      myList1.Add(new MyList1 { Code = 3 }); 
      return myList1; 
     } 

     public static List GetMyList2() 
     { 
      List myList2 = new List(); 
      myList2.Add(new MyList2 { Name = "1" }); 
      myList2.Add(new MyList2 { Name = "2" }); 
      myList2.Add(new MyList2 { Name = "3" }); 
      return myList2; 
     } 
    } 

    public interface IMyList 
    { 
    } 

    public class MyList1 : IMyList 
    { 
     public int Code { get; set; } 
    } 

    public class MyList2 : IMyList 
    { 
     public string Name { get; set; } 
    } 

    public enum MyListTypeEnum 
    { 
     MyList1, 
     MyList2 
    } 
} 

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