2010-09-28 17 views
5

La mia domanda esiste un modo per recuperare l'elenco di parametri con il suo valore utilizzando Reflection?Ottieni parametri di un attributo utilizzando Reflection

Desidero utilizzare la riflessione per ottenere l'elenco dei parametri da PropertyInfo.

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

non è OK. Poiché ci saranno molti attributi, che non sono di tipo autore.

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

risposta

0

Presumo per elenco di parametri, si intende un elenco di tutti gli usi di attributo?

In caso contrario, questo codice mostra come ottenere un attributo utilizzando la riflessione su un'intera classe. Ma dovresti essere in grado di prendere ciò di cui hai bisogno.

ecco un metodo per trovare tutti gli attributi di un certo tipo, di alcuna proprietà all'interno di 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,....); 
     } 

    } 
} 

Poi si potrebbe andare:

var testClass = new TestClass(); 

var results = GetAttributesFromClass(testClass); 

Inoltre, si può prendere il vostro public double version e string name come proprietà. Qualcosa di simile a questo:

public double version 
{ 
    get; 
    private set; 
} 

che permetterà version da impostare dal costruttore, e leggere da qualsiasi luogo.

+0

Grazie. Il mio caso è che non usare la classe statica. Quindi usando l'autore dell'autore = (Autore) attributo; non è OK. Voglio usare reflection per ottenere l'elenco dei parametri da PropertyInfo. – seasong

+0

Puoi definire la lista dei parametri? – PostMan

+0

La lista dei parametri è che posso ottenere ("Bill Gates", 2) dinamicamente usando la reflection e devo usare "Author" per castare l'attributo. Poiché ci saranno molti attributi di questo tipo, alcuni potrebbero non essere attributo Autore. – seasong

4

usando questo programma

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

} 

ottengo questo output:

alt text

0
string name = author.name; 

non è consentito perché il campo name non è pubblico. Funziona se rendi pubblico lo name?

+0

Spiacente è un errore di battitura, ho aggiunto il pubblico indietro. – seasong

+0

La tua ultima modifica rivela il tuo problema.Usa 'GetCustomAttributes' con un parametro type per filtrare e guarda solo gli attributi che sono' Author', oppure usa 'Author author = attributo come Author;' invece di un cast, per fare un controllo dinamico del tipo, e ignorare quelli che torna 'null'. –

0

Ho avuto lo stesso problema in una delle mie app. questa è la mia soluzione:

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

Ho testato il vostro esempio.

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

qui è uscita:

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