【问题标题】:Get parameters of an Attribute using Reflection使用反射获取属性的参数
【发布时间】:2015-02-02 21:25:50
【问题描述】:

我的问题是有什么方法可以使用反射来检索参数列表及其值?

我想使用反射从 PropertyInfo 中获取参数列表。

 Author author = (Author)attribute;
 string name = author.name;

不正常。因为会有很多Attribute,不是Author类型。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property,  AllowMultiple = true)]
public class Author : Attribute
{
    public Author(string name, int v)
    {
        this.name = name;
        version = v;
    }

    public double version;
    public string name;
}

public class TestClass
{
    [Author("Bill Gates", 2)]
    public TextBox TestPropertyTextBox { get; set; }
}

【问题讨论】:

    标签: c# reflection


    【解决方案1】:

    使用这个程序

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace ConsoleApplication1 {
        class Program {
            static void Main(string[] args) {
                Console.WriteLine("Reflecting TestClass");
                foreach (var property in typeof(TestClass).GetProperties()) {
                    foreach (Author author in property.GetCustomAttributes(typeof(Author), true).Cast<Author>()) {
                        Console.WriteLine("\tProperty {0} Has Author Attribute Version:{1}", property.Name, author.version);
                    }
                }
                var temp = new TestClass();
                Console.WriteLine("Reflecting instance of Test class ");
                foreach (var property in temp.GetType().GetProperties()) {
                    foreach (Author author in property.GetCustomAttributes(typeof(Author), true).Cast<Author>()) {
                        Console.WriteLine("\tProperty {0} Has Author Attribute Version:{1}", property.Name, author.version);
                    }
                }
            }
    
        }
    
        [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = true)]
        public class Author : Attribute {
            public Author(string name, int v) {
                this.name = name;
                version = v;
            }
    
            public double version;
            string name;
        }
    
        public class TestClass {
            [Author("Bill Gates", 2)]
            public TextBox TestPropertyTextBox { get; set; }
        }
    
    }
    

    我得到这个输出:

    【讨论】:

      【解决方案2】:

      我假设参数列表,你的意思是所有属性使用的列表?

      如果没有,此代码将向您展示如何使用整个类的反射来获取属性。但是你应该能够拿走你需要的东西。

      所以这是一种在TestClass内的任何属性上查找某种类型的所有属性的方法

      public IEnumberable<Result> GetAttributesFromClass(TestClass t)
      {
      
          foreach(var property in t.GetType().GetProperties())
          {
              foreach(Author author in property.GetCustomAttributes(typeof(Arthor), true))
              {
                   // now you have an author, do what you please
                   var version = author.version;
                   var authorName = author.name;
      
                   // You also have the property name
                   var name = property.Name;
      
                   // So with this information you can make a custom class Result, 
                   // which could contain any information from author, 
                   // or even the attribute itself
                   yield return new Result(name,....);
              }
      
          }
      }
      

      那么你可以去:

      var testClass = new TestClass();
      
      var results = GetAttributesFromClass(testClass);
      

      另外,您可能希望您的 public double versionstring name 成为属性。 像这样的:

      public double version
      {
          get; 
          private set;
      }
      

      这将允许从构造函数设置version,并从任何地方读取。

      【讨论】:

      • 谢谢。我的情况是不使用静态类。所以使用 Author author = (Author)attribute;不行。我想使用反射从 PropertyInfo 中获取参数列表。
      • 你能定义参数列表吗?
      • 参数列表是我可以使用反射动态获取 ("Bill Gates", 2) 必须使用 "Author" 来转换属性。因为会有很多这样的Attribute,有些可能不是Author属性。
      • 那么您可以遍历属性并获取所有属性?
      【解决方案3】:
      string name = author.name;
      

      不允许,因为字段 name 不是公共的。把name设为public可以吗?

      【讨论】:

      • 抱歉打错了,我把公众号加回来了。
      • 您的最新编辑揭示了您的问题。使用带有类型参数的GetCustomAttributes 进行过滤并仅查看Author 的属性,或者使用Author author = attribute as Author; 而不是强制转换,进行动态类型检查,并忽略返回的null .
      【解决方案4】:

      我在我的一个应用程序中遇到了同样的问题。这是我的解决方案:

      public static string GetAttributesData(MemberInfo member)
      {            
          StringBuilder sb = new StringBuilder();
          // retrives details from all attributes of member
          var attr = member.GetCustomAttributesData();
          foreach (var a in attr)
          {
              sb.AppendFormat("Attribute Name        : {0}", a)
                  .AppendLine();
              sb.AppendFormat("Constructor arguments : {0}", string.Join(",  ", a.ConstructorArguments))
                  .AppendLine();
              if (a.NamedArguments != null && a.NamedArguments.Count > 0 )
              sb.AppendFormat("Named arguments       : {0}", string.Join(",  ", a.NamedArguments))
                  .AppendLine();
              sb.AppendLine();
          }            
          return sb.ToString();
      }
      

      我已经测试了您的示例。

      var t = typeof (TestClass);
      var prop = t.GetProperty("TestPropertyTextBox", BindingFlags.Public | BindingFlags.Instance);
      var scan = Generator.GetAttributesData(prop);
      

      这里是输出:

      Attribute Name        : [Author("Bill Gates", (Int32)2)]
      Constructor arguments : "Bill Gates",  (Int32)2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-05
        • 1970-01-01
        • 1970-01-01
        • 2017-05-14
        • 2017-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多