2009-09-11 5 views
0

Интересно, может ли кто-нибудь мне помочь - я не много сделал с размышлениями, но понимаю основные принципы.Reflection - Рекурсивно перебирать свойства объекта в моих собственных сборках (Vb.Net/3.5)

То, что я пытаюсь сделать:

Я нахожусь в процессе разработки класса, который собирает много информации о локальной системе, сети, и т.д. ..., которые будут использоваться для автоматизированного отчет об ошибках. Вместо того, чтобы менять свой тестовый жгут каждый раз, когда я добавляю новое свойство, я бы (в идеале) хотел бы сериализовать лот как строку XML и просто отобразить это в текстовом поле.

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

[Не уверен, что я согласен с предположением, что что-либо сериализованное должно быть де-сериализуемым - MS говорит, что это функция «по дизайну», которую, я полагаю, я могу понять. Возможно, тег, указывающий на то, что он должен быть сериализован в любом случае, будет выгодным?]

Первоначальный подход состоял в том, чтобы сделать свойства доступными и настраиваемыми (с исключением исключения из сеттера), но объем работы по его очистке после этого кажется немного чрезмерным, и я хотел бы, чтобы свойства были доступны только для чтения окончательная версия.

Что мне нужна помощь с:

Мой текущий план использовать отражение рекурсивно перебирать каждого (общественной) собственности моего верхнего класса сбора. Проблема в том, что образцы, которые я видел, не рекурсивно обрабатывают вещи. Кроме того, я хочу только проверить свойства объекта, если он находится в одной из моих сборок. В противном случае просто вызовите .ToString на нем.

Если у меня нет проверки ограничивается моей сборкой, я предполагаю, что я буду получать (скажу) строка, которая затем содержит длину, которая в своей очереди, будет иметь метод .ToString ...

Для цели этого проекта, я могу почти гарантировать отсутствие циркулярных ссылок в моем коде, так как это будет использоваться только как инструмент разработки, поэтому я не тоже беспокоится о том, что он работает amok время от времени.

Буду признателен за некоторые примеры/рекомендации.

Большое спасибо заранее.

ответ

3

Это, надеюсь, поможет вам начать работу. Он печатает дерево непосредственно на консоли, поэтому вам нужно настроить выход XML. Затем измените метод IsMyOwnType, чтобы отфильтровать интересующие вас сборки, сейчас он заботится только о типах в той же самой сборке, что и сам.

Shared Sub RecurseProperties(o As Object, level As Integer) 
    For Each pi As PropertyInfo In o.GetType().GetProperties() 
     If pi.GetIndexParameters().Length > 0 Then Continue For 

     Console.Write(New String(" "c, 2 * level)) 
     Console.Write(pi.Name) 
     Console.Write(" = ") 

     Dim propValue As Object = pi.GetValue(o, Nothing) 
     If propValue Is Nothing Then 
      Console.WriteLine("<null>") 
     Else 
      If IsMyOwnType(pi.PropertyType) Then 
       Console.WriteLine("<object>") 
       RecurseProperties(propValue, level+1) 
      Else 
       Console.WriteLine(propValue.ToString()) 
      End If 
     End If 

    Next 
End Sub 

Shared Function IsMyOwnType(t As Type) As Boolean 
    Return t.Assembly Is Assembly.GetExecutingAssembly() 
End Function 
+0

Я стучал на что-то подобное и в конечном итоге с чем-то, что работает, но был спагетти код. Ваш пример намного более краток и отличная помощь - Большое спасибо – Basic

+0

Конечно, моя следующая проблема - перечисление списков ... Опять же, я нашел способ сделать это, но в настоящее время это беспорядок. Если/когда я получу код в презентабельном состоянии, я отправлю окончательную версию. – Basic

2

You версия расширения на C# для использования на любом объекте

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Reflection; 

namespace Extensions 
{ 
    public static class ObjectExtension 
    { 
     public static string ToStringProperties(this object o) 
     { 
      return o.ToStringProperties(0); 
     } 
    public static string ToStringProperties(this object o, int level) 
    { 
     StringBuilder sb = new StringBuilder(); 
     string spacer = new String(' ', 2 * level); 
     if (level == 0) sb.Append(o.ToString()); 
     sb.Append(spacer); 
     sb.Append("{\r\n"); 
     foreach (PropertyInfo pi in o.GetType().GetProperties()) 
     { 

      if (pi.GetIndexParameters().Length == 0) 
      { 
       sb.Append(spacer); 
       sb.Append(" "); 
       sb.Append(pi.Name); 
       sb.Append(" = "); 

       object propValue = pi.GetValue(o, null); 
       if (propValue == null) 
       { 
        sb.Append(" <null>"); 
       } else { 
        if (IsMyOwnType(pi.PropertyType)) 
        { 
         sb.Append("\r\n"); 
         sb.Append(((object)propValue).ToStringProperties(level + 1)); 
        } else{ 
         sb.Append(propValue.ToString()); 
        } 
       } 
       sb.Append("\r\n"); 
      } 
     } 
     sb.Append(spacer); 
     sb.Append("}\r\n"); 
     return sb.ToString(); 
    } 
    private static bool IsMyOwnType(Type t) 
{ 
    return (t.Assembly == Assembly.GetExecutingAssembly()); 
} 
} 
} 
+0

Это не код vb.net. – thecoolmacdude

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

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