2012-09-06 3 views
14

Sto provando a impostare un valore su una proprietà nidificata di classe dinamicamente utilizzando la riflessione. Qualcuno potrebbe aiutarmi a fare questo.Come impostare i siti nella proprietà nidificata mediante C# Reflection.?

Ho una classe Region come di seguito.

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

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

Ho un lettore di dati Oracle per fornire i valori dal cursore Rif.

che mi darà come

Id, nome, country_id, COUNTRY_NAME

ho potuto in grado di assegnare i valori alla Region.Id, Region.Name da sotto.

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

E per la proprietà Nested ho potuto in grado di fare i valori assegnare al come di seguito con la creazione di un'istanza leggendo la 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); 
} 

I valori di assegnazione sopra a Country.Id.

Ma poiché sto creando istanze tutte le volte in cui non sono riuscito a ottenere il valore Country.Id precedente se si utilizza il Next Country.Name.

Qualcuno potrebbe dire potrebbe assegnare valori al objItem(that is Region).Country.Id e objItem.Country.Name. Il che significa come assegnare valori alle Proprietà nidificate invece di creare istanze e assegnarle ogni volta.

Grazie in anticipo.!

+1

Eventuali duplicati di http://stackoverflow.com/questions/1954746/using-reflection -in-c-sharp-to-get-properties-of-a-nested-object –

risposta

35

Si dovrebbe essere chiamando PropertyInfo.GetValue utilizzando la proprietà Country per ottenere il paese, quindi PropertyInfo.SetValue utilizzando la proprietà Id-impostare l'ID del paese.

Quindi qualcosa di simile:

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

Grazie Caro .. Ha funzionato come un fascino .. :-) – Sravan

+0

Perché è accettato come risposta, genera un nullrif perché GetValue () restituisce null se il target non è ancora istanziato, il che porterà a un'eccezione di una riga furthe r. –

1

ottenere le proprietà Nest ad esempio, 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

Questa soluzione ha un grosso difetto, non funzionerà con elenchi generici. Ad esempio, si fornisce FirstObject.MyList [0] .MyValue si arresta semplicemente perché ignora la prima istanza [0] –