Je n'ai pas utiliser les attributs dans ma journée-à-jour de travail avant, mais j'ai lu à leur sujet.
Aussi, j'ai fait quelques tests, pour sauvegarder ce que je vais dire ici. Si je me trompe, en tout lieu, - n'hésitez pas à me dire cela :)
De ce que je sais, les attributs ne sont pas en agissant comme des classes régulières. Ils ne sont pas instanciés lorsque vous créez un objet auxquels ils s'appliquent, et non pas une instance statique, pas de 1 pour chaque instance de l'objet.
Ni à accéder à la classe à laquelle ils sont appliqués..
Au lieu de cela, ils agissent comme des propriétés (attributs? :P ) de la classe. Pas comme le .NET classe de propriétés, plus comme dans le "une propriété de verre est la transparence" de ce genre de propriété. Vous pouvez vérifier quels sont les attributs appliqués à une classe de la réflexion, et ensuite agir en conséquence. Ils sont essentiellement des méta-données attachées à la définition de la classe, et non pas les objets de ce type.
Vous pouvez essayer d'obtenir la liste des attributs d'une classe, une méthode, une propriété, etc etc.. Quand vous obtenez la liste de ces attributs - c'est là où ils seront instanciés. Ensuite, vous pouvez agir sur les données à l'intérieur de ces attributs.
E. g. le Linq tables, les propriétés ont des attributs qui définissent qui table/colonne, ils se réfèrent. Mais ces classes ne pas utiliser ces attributs. Au lieu de cela, le DataContext va vérifier les attributs de ces objets lorsqu'il vous permet de convertir expression linq arbres de code SQL.
Maintenant, pour certains d'exemples réels.. j'ai couru dans ces LinqPad, donc ne vous inquiétez pas à propos de l'étrange méthode Dump (). Je l'ai remplacé par de la Console.WriteLine pour rendre le code plus facile à comprendre pour les gens qui ne la connaissent pas :)
void Main()
{
Console.WriteLine("before class constructor");
var test = new TestClass();
Console.WriteLine("after class constructor");
var attrs = Attribute.GetCustomAttributes(test.GetType()).Dump();
foreach(var attr in attrs)
if (attr is TestClassAttribute)
Console.WriteLine(attr.ToString());
}
public class TestClassAttribute : Attribute
{
public TestClassAttribute()
{
DefaultDescription = "hello";
Console.WriteLine("I am here. I'm the attribute constructor!");
}
public String CustomDescription {get;set;}
public String DefaultDescription{get;set;}
public override String ToString()
{
return String.Format("Custom: {0}; Default: {1}", CustomDescription, DefaultDescription);
}
}
[Serializable]
[TestClass(CustomDescription="custm")]
public class TestClass
{
public int Foo {get;set;}
}
La console résultat de cette méthode est:
before class constructor
after class constructor
I am here. I'm the attribute constructor!
Custom: custm; Default: hello
Et l' Attribute.GetCustomAttributes(test.GetType())
retourne ce tableau:
(le tableau affiche toutes les colonnes disponibles pour toutes les entrées.. Donc non, l'attribut Serializable n'ont pas ces propriétés :) )
Avez d'autres questions? N'hésitez pas à demander!
UPD:
J'ai vu que vous poser une question: pourquoi les utiliser?
Un exemple, je vais vous parler de la XML-RPC.NET de la bibliothèque.
Vous créez votre XML-RPC classe de service, avec des méthodes qui représentera le xml-rpc méthodes. La chose principale est maintenant de: en XmlRpc les noms de méthode peuvent avoir certains caractères spéciaux, comme des points. Donc, vous pouvez avoir un flexlabs.ProcessTask() xml rpc méthode.
Vous définissez cette classe comme suit:
[XmlRpcMethod("flexlabs.ProcessTask")]
public int ProcessTask_MyCustomName_BecauseILikeIt();
Cela me permet de m'nom de la méthode dans la façon dont je l'aime, tout en continuant d'utiliser le nom public comme il se doit.