2010-09-28 9 views
5

Ma question est-il possible de récupérer la liste de paramètres avec sa valeur en utilisant Reflection?Obtenir les paramètres d'un attribut en utilisant la réflexion

Je souhaite utiliser la réflexion pour obtenir la liste de paramètres de PropertyInfo.

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

n'est pas OK. Comme il y aura beaucoup d'attributs, ce qui n'est pas typeof auteur.

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

Répondre

0

Je suppose que par liste de paramètres, vous voulez dire une liste de toutes les utilisations d'attributs?

Sinon, ce code vous montre comment obtenir un attribut en utilisant la réflexion sur une classe entière. Mais vous devriez être capable de prendre ce dont vous avez besoin.

Voici donc une méthode pour trouver tous les attributs d'un certain type, sur une propriété à l'intérieur d'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,....); 
     } 

    } 
} 

Ensuite, vous pouvez aller:

var testClass = new TestClass(); 

var results = GetAttributesFromClass(testClass); 

, vous voudrez peut-être aussi votre public double version et string name être des propriétés. Quelque chose comme ceci:

public double version 
{ 
    get; 
    private set; 
} 

qui permettra version à définir à partir du constructeur, et lu partout.

+0

Merci. Mon cas est que n'utilisez pas la classe statique. Donc, en utilisant Auteur auteur = (Auteur) attribut; n'est pas OK. Je veux utiliser la réflexion pour obtenir la liste des paramètres de PropertyInfo. – seasong

+0

Pouvez-vous définir une liste de paramètres? – PostMan

+0

La liste des paramètres est que je peux obtenir ("Bill Gates", 2) dynamiquement en utilisant la réflexion avec devoir utiliser "Author" pour lancer l'attribut. Parce qu'il y aura beaucoup de tels attributs, certains peuvent ne pas être l'attribut d'auteur. – seasong

4

utilisant ce programme

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

} 

Je reçois cette sortie:

alt text

0
string name = author.name; 

n'est pas autorisé car le champ name n'est pas publique. Cela fonctionne-t-il si vous rendez public name?

+0

Désolé c'est une faute de frappe, j'ai ajouté le public. – seasong

+0

Votre dernière modification révèle votre problème.Utilisez 'GetCustomAttributes' avec un paramètre de type pour filtrer et ne regarder que les attributs qui sont' Author', ou bien utilisez 'Author author = attribute comme Author;' au lieu d'un cast, pour faire un contrôle de type dynamique, et ignorer les uns qui reviennent 'null'. –

0

J'ai eu le même problème dans une de mes applications. ceci est ma solution:

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

J'ai testé votre exemple.

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

ici est sortie:

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