2010-09-28 17 views
5

Mi pregunta es ¿hay alguna forma de recuperar la lista de parámetros con su valor usando Reflection?Obtener los parámetros de un atributo usando la Reflexión

Quiero usar la reflexión para obtener la lista de parámetros de PropertyInfo.

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

no está bien. Como habrá muchos Atributo, que no es typeof Autor.

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

Respuesta

0

Supongo que por lista de parámetros, ¿quieres decir una lista de todos los usos de atributos?

Si no, este código muestra cómo obtener un atributo utilizando la reflexión en una clase completa. Pero deberías poder tomar lo que necesitas.

Así que aquí es un método para encontrar todos los atributos de un determinado tipo, en cualquier propiedad dentro de un 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,....); 
     } 

    } 
} 

entonces usted podría ir:

var testClass = new TestClass(); 

var results = GetAttributesFromClass(testClass); 

Además, es posible que desee su public double version y string name para ser propiedades. Algo como esto:

public double version 
{ 
    get; 
    private set; 
} 

que permitirá version que se fijará desde el constructor, y leer desde cualquier lugar.

+0

Gracias. Mi caso es que no utilizo la clase estática. Entonces, usando el autor Autor = (Autor) atributo; No está bien. Quiero usar la reflexión para obtener la lista de parámetros de PropertyInfo. – seasong

+0

¿Se puede definir la lista de parámetros? – PostMan

+0

La lista de parámetros es que puedo obtener ("Bill Gates", 2) dinámicamente utilizando la reflexión y tengo que usar "Autor" para convertir el atributo. Debido a que habrá muchos de tales atributos, algunos pueden no ser atributos de autor. – seasong

4

uso de este programa

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

} 

puedo obtener este resultado:

alt text

0
string name = author.name; 

no está permitido porque el campo name no es pública. ¿Funciona si haces público name?

+0

Lo siento, es un error tipográfico, agregué al público. – seasong

+0

Su última edición revela su problema.Utilice 'GetCustomAttributes' con un parámetro de tipo para filtrar y solo observe los atributos que son' Author', o bien use 'Author author = attribute como Author;' en lugar de un molde, para hacer una comprobación dinámica de tipo, e ignore los que que vuelven 'nulo'. –

0

tuve el mismo problema en una de mis aplicaciones. esta es mi solución:

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

he probado su ejemplo.

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

aquí es la salida:

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