Получить параметры атрибута, используя отражение - PullRequest
5 голосов
/ 28 сентября 2010

Мой вопрос, есть ли способ получить список параметров с его значением, используя Reflection?

Я хочу использовать отражение, чтобы получить список параметров из PropertyInfo.

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

не в порядке. Так как будет много атрибутов, которые не являются typeof 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; }
}

Ответы [ 4 ]

4 голосов
/ 28 сентября 2010

с помощью этой программы

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; }
    }

}

Я получаю этот вывод:

alt text

0 голосов
/ 02 февраля 2015

У меня была такая же проблема в одном из моих приложений. это мое решение:

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
0 голосов
/ 28 сентября 2010
string name = author.name;

не допускается, поскольку поле name не является открытым. Это работает, если вы делаете name публичным?

0 голосов
/ 28 сентября 2010

Я предполагаю под списком параметров, вы имеете в виду список всех атрибутов использования?

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

Итак, вот метод, позволяющий найти все атрибуты определенного типа в любом свойстве внутри 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 version и string name были свойствами. Примерно так:

public double version
{
    get; 
    private set;
}

Что позволит установить version из конструктора и читать из любого места.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...