2013-05-01 14 views
2

Я пытаюсь пройти через класс и его дочерние классы для получения переданных значений.Цитирование через классы и дочерние классы для извлечения свойств и значений в C#

Вот мой класс:

public class MainClass 
{ 
    bool IncludeAdvanced { get; set; } 

    public ChildClass1 ChildClass1 { get; set; } 
    public ChildClass2 ChildClass2 { get; set; } 
} 

Вот мой код до сих пор

GetProperties<MainClass>(); 

private void GetProperties<T>() 
{ 
    Type classType = typeof(T); 
    foreach (PropertyInfo property in classType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) 
    { 
     WriteToLog(property.Name + ": " + property.PropertyType + ": " + property.MemberType); 
     GetProperties<property>(); 
    } 
} 

Два вопроса:

  1. Что я перехожу к GetProperties, чтобы передать дочерний класс, для чтобы затем пропустить его свойства, если это класс?
  2. Как получить значение из элемента свойства, если оно не является классом?

Надеюсь, это все имеет смысл. Если нет, не стесняйтесь спрашивать, и я попробую и уточню.

Благодаря

+0

Что вы имеете в виду «получить значение из объекта имущества, если это не класс»? Вы хотите получить значение _value, присвоенное этому свойству? Итак, загрузите _instance_ из 'ChildClass1', который был назначен этому свойству? EDIT: Или вы имеете в виду, если свойство является value-type (struct)? Если это так, не имеет значения, все равно это сработает. –

+0

Что именно вы подразумеваете под «значением от свойства»? Вы не передаете какой-либо экземпляр MainClass в GetProperties, поэтому откуда это должно взяться? – Heinzi

+0

Извинения. Немного смущал вещи и пропустил половину моего вопроса. ;-) Моя основная цель - передать экземпляр MainClass, например. со значениями в, затем прокрутите его, и это дочерние классы и получите значения, установленные против любых значений. Надеюсь, это очистит все! Извиняюсь! –

ответ

4

Крис уже ответил на первую часть вашего вопроса, поэтому я не буду повторять это. Во второй части, как только у вас есть экземпляр MainClass, вы можете просто использовать (метко назвал) PropertyInfo.GetValue method:.

object value = property.GetValue(myInstance, null); 

(Если вы используете .NET 4.5, вы можете omit the second (null) parameter Более ранние версии требуют, ., хотя)

В конце концов, ваш код может выглядеть следующим образом (я беззастенчиво скопирована и расширенная Криса версия) (непроверенные):

private void GetProperties<T>(T instance) 
{ 
    GetProperties(typeof(T), instance); 
} 

private void GetProperties(Type classType, object instance) 
{ 
    foreach (PropertyInfo property in classType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) 
    { 
     WriteToLog(property.Name + ": " + property.PropertyType + ": " + property.MemberType); 

     object value = property.GetValue(instance, null); 
     if (value != null) { 
      WriteToLog(value.ToString()); 
      GetProperties(property.PropertyType, value); 
     } 
    } 
} 

Обратите внимание, что этот код не сработает, если любой из ваших объектов используйте индекс ed properties (C# indexers или properties with parameters в VB). В этом случае GetValue должен быть снабжен соответствующим индексом или параметром.

5

Вы можете легко переписать его рекурсивным без дженериков:

private void GetProperties<T>() 
{ 
    GetProperties(typeof(T)); 
} 

private void GetProperties(Type classType) 
{ 
    foreach (PropertyInfo property in classType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) 
    { 
     WriteToLog(property.Name + ": " + property.PropertyType + ": " + property.MemberType); 
     GetProperties(property.PropertyType); 
    } 
} 

Не уверен, что на второй вопрос: «Как я могу получить значение из объекта имущества, если оно не является класс "(я отредактирую/обновить, когда мы это выясним)

+1

+1, что я собирался написать. NB: общая версия не будет работать для рекурсии, поскольку аргументы универсального типа должны быть известны * во время компиляции * (что работает для 'GetProperties ', но не для 'GetProperties '). – Heinzi

+0

@Heinzi Ну, вы можете использовать отражение, чтобы использовать только общую версию ... но это было бы глупо. –

0

Что касается вашего второго вопроса, если вы хотите получить значение из объекта свойства, вы должны предоставить объект Type. Хейнзи объяснил, как получить стоимость имущества. Я предоставляю версию оболочки без дженериков.

private static void ResolveTypeAndValue(object obj) 
    { 
     var type = obj.GetType(); 
     foreach (var p in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)) 
     { 
      if (p.PropertyType.IsClass && p.PropertyType != typeof(string)) 
      { 
       var currentObj = p.GetValue(obj); 
       ResolveTypeAndValue(currentObj); 
      } 
      else 
       Console.WriteLine("The value of {0} property is {1}", p.Name, p.GetValue(obj)); 
     } 
    } 
0
public IEnumerable<PropertyInfo> GetProperties(Type type) 
    { 
     //Just to avoid the string 
     if (type == typeof(String)) return new PropertyInfo[] { }; 
     var properties = type.GetProperties().ToList(); 
     foreach (var p in properties.ToList()) 
     { 
      if (p.PropertyType.IsClass) 
       properties.AddRange(GetProperties(p.PropertyType)); 
      else if (p.PropertyType.IsGenericType) 
      { 
       foreach (var g in p.PropertyType.GetGenericArguments()) 
       { 
        if (g.IsClass) 
         properties.AddRange(GetProperties(g)); 
       } 
      } 
     } 
     return properties; 

    } 

Попробуйте это какие перебирает свойства только если класс

 Смежные вопросы

  • Нет связанных вопросов^_^