2010-03-03 3 views
3

Возьмите этот класс в качестве образца:Recurse через свойство класса

[AttributeUsage(AttributeTargets.All, AllowMultiple=true)] 
public class BugFixAttribute : System.Attribute 
{ 
    public int BugId { get; private set; } 
    public string Programmer { get; private set; } 
    public DateTime Date { get; private set; } 
    public string Comments { get; set; } 
    public string RefersTo { get; set; } 

    public BugFixAttribute(int bugId = 0, string programmer = "") 
    { 
     this.BugId = bugId; 
     this.Programmer = programmer; 
     Date = DateTime.Now; 
    } 
} 

И я хочу, чтобы дисквалифицировать через свойство использовать как:

object[] attr = info.GetCustomAttributes(typeof(BugFixAttribute), false); 
foreach (object attribute in attr) 
{ 
    BugFixAttribute bfa = (BugFixAttribute) attribute; 
    Debug.WriteLine(string.Format("\nBugId: {0}", bfa.BugId)); 
    Debug.WriteLine(string.Format("Programmer: {0}", bfa.Programmer)); 
    //... 
} 

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

+1

ли вы на самом деле означает рекурсии, или действительно ли вы имеете в виду итерацию? –

+1

@ Марк Байерс, учитывая пример цикла, я подозреваю, что итерация, но я себя отвращаю. – kenny

+1

@kenny: Да, я тоже так думаю. Оставь меня за меня. –

ответ

6

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

Пример Синтаксис:

/// <summary>This Method Does Something</summary> 
/// <BugFix BugId="1234" Programmer="Bob" Date="2/1/2010">Fix Comments</BugFix> 
public void MyMethod() 
{ 
    // Do Something 
} 
+0

, тогда простой xpath получит все, что вам нужно, но производственный код будет неограничен. +1 –

+0

+1 за вежливость. me -> атрибуты для инертного переходного мета ... что !? вот ваш розовый промах. –

4

Да, если вы используете отражение:

Type t = bfa.GetType(); 
PropertyInfo[] properties = t.GetProperties(); 
foreach(var prop in properties) 
{ 
    Debug.WriteLine(string.Format("{0}: {1}", prop.Name,prop.GetValue(bfa,null))); 
} 

Это будет печатать имя и значение всех открытых свойств в БФА. Вы можете проверить свойство CanRead в PropertyInfo, чтобы проверить, можно ли его читать (т. Е. Если он объявляет getter). Пример не будет выполнен, если одно из свойств доступно только для чтения или проиндексировано - если это может произойти, вам нужно проверить его в коде.

0

Если я правильно прочитал вопрос, вы ищете более простой способ написать информацию о классе, не так ли? У вас есть два варианта:

  1. отражение, для очень общего решения, которое будет Prolly выхода слишком много информации (в предположении, что это Java - или .NET, которые мне сказали, очень же .. .)
  2. определяют метод ToString(), и вызвать Debug.WriteLine (БФ)

Решение 1, вероятно пути излишества. Вероятно, вы получите результат для тех вещей, которые вам не нужны, и вы не сможете получить частные значения.

Решение 2 - это простой способ.

 
public class BugFixAttribute : System.Attribute 
{ 
... 

public String toString(){ 
    return string.Format("\nBugId: {0}\nProgrammer: {1}", this.BugId, this.Programmer)); 
} 
} 
+0

Я бы не сказал, что излишне использовать отражение, это похоже на 30 секунд кода, и вы можете получить частных членов. Тем не менее, ToString() по-прежнему является хорошим вариантом, если его требования подходят, но я не уверен, что они это делают. –

+0

@Paul Creasey: Вы совершенно правы, что это зависит от его требований. И это не так много кода. Я думаю, что излишним с точки зрения вывода, который будет сбрасываться, если используются другие объекты, а не в строках кода. Это может быть и удар производительности - IIRC, рефлексия медленная.Кроме того, я удивлен тем, что рефлексия будет иметь доступ к личным данным, что, по-видимому, нарушает цель обозначения членов как частных. – atk

0
foreach (var (BugFixAttribute)attribute in attr) 
{ 
    foreach(PropertyInfo prop in attribute.GetType().GetProperties()) 
    { 
     Debug.WriteLine(string.Format("{0}: {1}", prop.name,prop.GetValue(attribute,null)); 
    } 
} 
2

Я люблю Linq для такого рода вещи

var props = from b in info.GetCustomAttributes(typeof(BugFixAttribute), false) 
      from p in b.GetType().GetProperties() 
      select new { 
        Name = p.Name, 
        Value = p.GetValue(p.GetValue(b, null)) 
        }; 

foreach(var prop in props) 
{ 
    Debug.WriteLine(string.Format("{0}: {1}", prop.Name, prop.Value)); 
} 
Смежные вопросы