通过类的属性进行递归

时间:2010-03-03 21:39:15

标签: c# reflection recursion properties attributes

以此示例类为例:

    [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(),是否有办法或者我必须将其写出来。

5 个答案:

答案 0 :(得分: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
}

答案 1 :(得分: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)));
}

这将在 bfa 中打印所有公共属性的名称和值。您可以检查PropertyInfo上的CanRead属性以检查是否可以读取它(即,如果它声明了getter)。如果其中一个属性是只读的或已编制索引,则该示例将失败 - 如果发生这种情况,则需要在代码中检查它。

答案 2 :(得分: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));
}

答案 3 :(得分:0)

如果我正确地阅读了这个问题,那么你正在寻找一种更简单的方法来写出课堂信息,对吧?你有两个选择:

  1. 反思,对于一个非常通用的解决方案,它会输出过多的信息(假设这是java - 或者我被告知的.NET非常相同......)
  2. 定义toString()方法,并调用Debug.WriteLine(bfa)
  3. 解决方案1可能 方式 过度杀伤。你可能会得到你不想要的东西的输出,你将无法获得私人价值。

    解决方案2是简单的方法。

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

答案 4 :(得分: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));
    }
}