2011-02-26 3 views
1

Voici ma définition d'attribut:C# - Énumération Attributs personnalisés par réflexion

[AttributeUsage(AttributeTargets.Field)] 
public class Optional : System.Attribute 
{ 
    public Optional() 
    { 
    } 
} 

En MyClass:

[Optional] public TextBox Name; 

Enfin, dans une autre fonction:

typeof(MyClass).GetFields().ToList<FieldInfo>().ForEach(x => writer.WriteLine(
    x.FieldType + " is called " + 
    x.Name + " and has attributes " + 
    x.GetCustomAttributes(true)[0] 
)); 

Le problème est que je reçois une erreur pour l'index 0. Je veux juste vérifier les champs où l'attribut est appliqué. L'erreur disparaît lorsque je supprime x.GetCustomAttributes(true)[0].

erreur exacte:

Exception Détails: System.IndexOutOfRangeException: index était en dehors des limites du tableau.

Erreur Source:

Line 63:    } 
Line 64: 
Line 65:    typeof(T).GetFields().ToList<FieldInfo>().ForEach(x => writer.WriteLine(x.FieldType + " is called " + 
Line 66:     x.Name + " and has attributes " + 
Line 67:     x.GetCustomAttributes(true)[0]+ "</br>")); 
+0

Quelle est l'erreur? – harpo

+0

Ajouté - Gardez à l'esprit ceci disparaît si je supprime la partie "GetCustomAttributes". –

Répondre

2

On dirait qu'il pourrait y avoir deux questions ici. Pour trouver tous les champs qui ont votre [option] attribut, vous voulez:

typeof(MyClass).GetFields().Where(
    f => f.GetCustomAttributes(typeof(OptionalAttribute), true).Any()) 

Pour écrire les attributs personnalisés sur tous vos champs, vous voulez:

typeof(MyClass).ToList<FieldInfo>().ForEach(x => 
{ 
writer.WriteLine(
    x.FieldType + " is called " + 
    x.Name + " and has attributes " + 
    string.Join(", ", x.GetCustomAttributes(true).Select(a => a.ToString()).ToArray())); 
}); 
+0

La première partie que vous avez donnée m'a permis de trouver la solution la plus éloquente à mon problème. Je vous remercie. –

1

Comme vous semblez avoir rassemblé, vous obtenez cette erreur parce que vous essayez d'obtenir l'élément 0e d'un tableau vide, ce qui est bien sûr illégal. Vous devez filtrer les champs sans les attributs d'abord, comme ceci:

var fields = from fieldInfo in typeof(MyClass).GetFields() 
      let Attributes = fieldInfo.GetCustomAttributes(true) 
      where Attributes.Any() 
      select new { fieldInfo.FieldType, fieldInfo.Name, Attributes }; 

foreach (var field in fields) 
{ 
    writer.WriteLine(field.FieldType + " is called " + 
        field.Name + " and its first attribute is " + 
        field.Attributes.First()); 
} 

Si vous êtes particulièrement intéressé à ceux qui OptionalAttribute, alors vous êtes probablement quelque chose comme ceci:

var fields = from fieldInfo in typeof(MyClass).GetFields() 
      let attributes = fieldInfo.GetCustomAttributes(true).OfType<OptionalAttribute>() 
      where attributes.Any() 
      select new { fieldInfo.FieldType, fieldInfo.Name, Attribute = attributes.Single() }; 

foreach (var field in fields) 
{ 
    writer.WriteLine(field.FieldType + " is called " + 
        field.Name + " and its OptionalAttribute is " + 
        field.Attribute); 
} 
+0

Vous avez cloué que le problème était avec plusieurs éléments n'ayant pas l'attribut défini. J'aimerais pouvoir accepter votre réponse aussi. –

1

Vérifiez l'existence d'attribut comme ceci:

x.GetCustomAttributes(true).Any(item => item is OptionalAttribute) 

Je suppose que vous renommer votre Optional attribut OptionalAttribute comme tous les attributs doivent avoir le suffixe "Attribute".

Questions connexes