2012-09-06 3 views
14

मैं प्रतिबिंब का उपयोग कर गतिशील रूप से कक्षा की एक नेस्टेड संपत्ति के लिए मूल्य निर्धारित करने की कोशिश कर रहा हूं। क्या कोई मुझे ऐसा करने में मदद कर सकता है।सी # प्रतिबिंब का उपयोग कर नेस्टेड संपत्ति में वाउस कैसे सेट करें?

मेरे पास नीचे की तरह Region कक्षा है।

public class Region 
{ 
    public int id; 
    public string name; 
    public Country CountryInfo; 
} 

public class Country 
{ 
    public int id; 
    public string name; 
} 

मेरे पास रेफ कर्सर से मान प्रदान करने के लिए ओरेकल डेटा रीडर है।

जो मुझे दे देंगे के रूप में

आईडी, नाम, country_id, COUNTRY_NAME

मैं कर सकता मूल्यों, Region.Name नीचे से Region.Id को प्रदान करने में सक्षम।

FieldName="id" 
prop = objItem.GetType().GetProperty(FieldName, BindingFlags.Public | BindingFlags.Instance); 
prop.SetValue(objItem, Utility.ToLong(reader_new[ResultName]), null); 

और नेस्टेड संपत्ति के लिए मैं पढ़ FIELDNAME द्वारा एक उदाहरण बनाकर नीचे के रूप में करने के लिए असाइन मूल्यों ऐसा करने में सक्षम किया जा सका।

FieldName="CountryInfo.id" 

if (FieldName.Contains('.')) 
{ 
    Object NestedObject = objItem.GetType().GetProperty(Utility.Trim(FieldName.Split('.')[0]), BindingFlags.Public | BindingFlags.Instance); 

    //getting the Type of NestedObject 
    Type NestedObjectType = NestedObject.GetType(); 

    //Creating Instance 
    Object Nested = Activator.CreateInstance(typeNew); 

    //Getting the nested Property 
    PropertyInfo nestedpropinfo = objItem.GetType().GetProperty(Utility.Trim(FieldName.Split('.')[0]), BindingFlags.Public | BindingFlags.Instance); 

    PropertyInfo[] nestedpropertyInfoArray = nestedpropinfo.PropertyType.GetProperties(); 
    prop = nestedpropertyInfoArray.Where(p => p.Name == Utility.Trim(FieldName.Split('.')[1])).SingleOrDefault(); 

    prop.SetValue(Nested, Utility.ToLong(reader_new[ResultName]), null); 
    Nestedprop = objItem.GetType().GetProperty(Utility.Trim(FieldName.Split('.')[0]), BindingFlags.Public | BindingFlags.Instance); 

    Nestedprop.SetValue(objItem, Nested, null); 
} 

Country.Id के लिए ऊपर असाइन मान।

लेकिन चूंकि मैं पिछले और उदाहरण के लिए उदाहरण बना रहा हूं क्योंकि मैं अगले देश के लिए पिछले Country.Id मान प्राप्त नहीं कर पा रहा था।

क्या कोई बता सकता है कि objItem(that is Region).Country.Id और objItem.Country.Name पर मान असाइन कर सकता है। जिसका अर्थ है कि उदाहरण बनाने और हर बार असाइन करने के बजाय नेस्टेड गुणों को मान असाइन करना है।

अग्रिम धन्यवाद।

+1

http://stackoverflow.com/questions/1954746/using-reflection की संभावित डुप्लिकेट -in-c-sharp-to-get-property-of-a-nested-object –

उत्तर

35

आप को Id संपत्ति का उपयोग कर Country संपत्ति का उपयोग कर देश को पाने के लिए, तो PropertyInfo.SetValuePropertyInfo.GetValue बुला जाना चाहिए देश पर सेट आईडी।

तो कुछ इस तरह:

public void SetProperty(string compoundProperty, object target, object value) 
{ 
    string[] bits = compoundProperty.Split('.'); 
    for (int i = 0; i < bits.Length - 1; i++) 
    { 
     PropertyInfo propertyToGet = target.GetType().GetProperty(bits[i]); 
     target = propertyToGet.GetValue(target, null); 
    } 
    PropertyInfo propertyToSet = target.GetType().GetProperty(bits.Last()); 
    propertyToSet.SetValue(target, value, null); 
} 
+0

धन्यवाद प्रिय .. यह एक आकर्षण की तरह काम करता है .. :-) – Sravan

+0

यह उत्तर के रूप में क्यों स्वीकार किया जाता है, यह एक nullref फेंकता है क्योंकि GetValue () लक्ष्य को तत्काल नहीं किया गया है, जो शून्य को वापस कर रहा है, जिससे अपवाद एक लाइन फर्ट हो जाएगा आर। –

1

नेस्ट गुण जैसे हो जाओ, Developer.Project.Name

private static System.Reflection.PropertyInfo GetProperty(object t, string PropertName) 
      { 
       if (t.GetType().GetProperties().Count(p => p.Name == PropertName.Split('.')[0]) == 0) 
        throw new ArgumentNullException(string.Format("Property {0}, is not exists in object {1}", PropertName, t.ToString())); 
       if (PropertName.Split('.').Length == 1) 
        return t.GetType().GetProperty(PropertName); 
       else 
        return GetProperty(t.GetType().GetProperty(PropertName.Split('.')[0]).GetValue(t, null), PropertName.Split('.')[1]); 
      } 
+0

इस समाधान में एक बड़ा दोष है, यह सामान्य सूची के साथ काम नहीं करेगा। उदाहरण के लिए आप FirstObject.MyList [0] प्रदान करते हैं। MyValue बस क्रैश हो जाएगा क्योंकि यह [0] पहले उदाहरण को अनदेखा करता है –

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