2011-02-05 7 views
8

का उपयोग कर जेनेरिक सूची/संग्रह में आइटम जोड़ें मैं प्रतिबिंब का उपयोग कर जेनेरिक सूची में कोई आइटम जोड़ना चाहता हूं। विधि "DoSomething" में, मैं, निम्न पंक्ति को समाप्त करने केप्रतिबिंब

pi.PropertyType.GetMethod("Add").Invoke(??????) 

कोशिश कर रहा हूँ, लेकिन मैं त्रुटि के विभिन्न प्रकार के हो रही है।

नीचे मेरा पूरा कोड

public class MyBaseClass 
{   
    public int VechicleId { get; set; }   
}  
public class Car:MyBaseClass 
{ 
    public string Make { get; set; } 
}  
public class Bike : MyBaseClass 
{ 
    public int CC { get; set; } 
}   
public class Main 
{ 
    public string AgencyName { get; set; } 
    public MyBaseCollection<Car> lstCar {get;set;} 

    public void DoSomething() 
    { 
     PropertyInfo[] p =this.GetType().GetProperties(); 
     foreach (PropertyInfo pi in p) 
     { 
      if (pi.PropertyType.Name.Contains("MyBaseCollection")) 
      { 
       //Cln contains List<Car> 
       IEnumerable<MyBaseClass> cln = pi.GetValue(this, null) as IEnumerable<MyBaseClass>; 

       **//Now using reflection i want to add a new car to my object this.MyBaseCollection** 
       pi.PropertyType.GetMethod("Add").Invoke(??????) 
      } 
     }  
    } 
} 

कोई भी विचार/सुझाव है?

+0

MyBaseCollection का प्रकार क्या है? क्या यह एक सूची के समान है? IENumerable को लागू करने वाले सभी वर्गों को एक विधि जोड़ने की गारंटी नहीं है। – JoeyRobichaud

+0

@JoeRobich: MyBaseCollection अपने संग्रह कार्यान्वयन है जो IList से लिया गया है, यहां तक ​​कि सूची के लिए भी जवाब मेरी समस्या का समाधान करना चाहिए ... – kayak

उत्तर

18

मुझे लगता है कि आह्वान नहीं है आप चाहते हैं:

// Cast to IEnumerable<MyBaseClass> isn't helping you, so why bother? 
object cln = pi.GetValue(this, null); 

// Create myBaseClassInstance. 
// (How will you do this though, if you don't know the element-type?) 
MyBaseClass myBaseClassInstance = ... 

// Invoke Add method on 'cln', passing 'myBaseClassInstance' as the only argument. 
pi.PropertyType.GetMethod("Add").Invoke(cln, new[] { myBaseClassInstance }); 

के बाद से आप नहीं जानते कि क्या संग्रह का तत्व-प्रकार होने वाला है (कार, बाइक, साइकिल इत्यादि हो सकता है) आपको एक उपयोगी कलाकार ढूंढना मुश्किल लगेगा। उदाहरण के लिए, हालांकि आप कहते हैं कि संग्रह निश्चित रूप सेIList<SomeMyBaseClassSubType> लागू करेगा, यह IList<T> लागू नहीं होने के बाद से उपयोगी नहीं है। बेशक, IEnumerable<MyBaseClass>को कास्टिंग सफल होना चाहिए, लेकिन यह आपकी मदद नहीं करेगा क्योंकि यह उत्परिवर्तन का समर्थन नहीं करता है। दूसरी तरफ, यदि आपके संग्रह-प्रकार ने गैर-जेनेरिक IList या ICollection प्रकारों को लागू किया है, तो उन लोगों को कास्ट करना आसान हो सकता है।

लेकिन अगर आप यकीन रहे कि संग्रह को लागू करेगा IList<Car> (यानी आप पहले से संग्रह के घटक-प्रकार जानते हैं), चीजों को आसान कर रहे हैं:

// A much more useful cast. 
IList<Car> cln = (IList<Car>)pi.GetValue(this, null); 

// Create car. 
Car car = ... 

// The cast helped! 
cln.Add(car); 
+0

यह काम किया ... – kayak

+0

आईएलआईस्ट में आइटम जोड़ना निश्चित रूप से काम करेगा लेकिन मेरे मामले में मैं IENumerable bcos पर कास्ट टाइप करने की आवश्यकता है .. मेरे पास जेनेरिक प्रकार के लिए बेस क्लास है .. "IList cln = (IList ) pi.GetValue (यह, शून्य);" ... तो आपका पहला सुझाव तैयार हुआ ... (मैं अन्य कोडिंग आवश्यकताओं के लिए ienumerable में परिवर्तित कर रहा हूं) – kayak

+0

Ques: // (यदि आप तत्व-प्रकार को नहीं जानते हैं, तो आप यह कैसे करेंगे?) उत्तर: मुझे ऑब्जेक्ट में अलग-अलग जगहों से मूल्य मिलते हैं पदानुक्रम ...., रनटाइम पर व्युत्पन्न कक्षा नहीं बना रहा .. ऊपर कोड stackoverflow prupose के लिए नमूना है ..(वास्तविक समय यह अधिक जटिल है।) – kayak

0

typeof<List<>>.GetMethods के साथ शुरू, आप संपत्ति की एक विधि है, लेकिन संपत्ति के प्रकार की एक विधि

0

तुम सिर्फ सभी को एक साथ प्रतिबिंब से बचने कर सकते हैं और का उपयोग करें:

List<MyBaseClass> lstCar { get; set; } 

lstCar.Add((MyBaseClass)new Car()); 

तुम भी एक इंटरफ़ेस या अमूर्त तरीकों का उपयोग कर विचार कर सकते हैं ...

+0

मुझे कुछ सामान्य तरीके की आवश्यकता है, ऊपर कोड सिर्फ sample..in वास्तविक समय है, मुझे इसे कई pruposes – kayak

+0

के लिए चाहिए, आपको विरासत के साथ इसे दूर करने में सक्षम होना चाहिए, मुझे व्यक्तिगत रूप से लगता है कि प्रतिबिंब का उपयोग कक्षाओं और उप-वर्गों को सही तरीके से संरचित किया गया तो अनावश्यक होगा। – Rob

4

एक विकल्प के रूप में ... बस मत करो; गैर सामान्य IList इंटरफेस पर विचार करें:

IList list = (IList) {... get value ...} 
list.Add(newItem); 

हालांकि यह सब सामान्य संग्रह के लिए अनिवार्य IList लागू करने के लिए नहीं है, वे काफी सभी करते हैं, क्योंकि यह मूल ढांचे कोड के इस तरह के एक बहुत मज़बूत बनाता है।

+0

मैंने इसका जिक्र किया, लेकिन मुझे लगता है कि ओपी का संग्रह वर्ग उसका अपना है। इस मामले में, यह संदिग्ध है कि गैर-सामान्य इंटरफेस लागू किया गया है। :) – Ani