No he usado atributos en mi trabajo diario, pero he leído sobre ellos. También hice algunas pruebas para respaldar lo que voy a decir aquí. Si estoy equivocado en cualquier lugar, no dude en decirme esto :)
Por lo que sé, los atributos no están actuando como clases regulares. No se crean instancias cuando se crea un objeto al que se aplican, ni una instancia estática, ni 1 por cada instancia del objeto. Ni acceden a la clase a la que se aplican ...
En su lugar, actúan como propiedades (¿atributos ?: P) de la clase. No como la .NET clase propiedades, más como en el tipo de propiedad "una propiedad del vidrio es transparencia".Puede verificar qué atributos se aplican a una clase desde la reflexión, y luego actuar en consecuencia. En esencia, son metadatos que se adjuntan a la definición de clase, no los objetos de ese tipo.
Puede tratar de obtener la lista de atributos en una clase, método, propiedad, etc., etc. Cuando obtenga la lista de estos atributos, aquí es donde se crearán las instancias. Entonces puede actuar sobre los datos dentro de estos atributos.
E.g. las tablas de Linq, las propiedades tienen atributos que definen a qué tabla/columna se refieren. Pero estas clases no usan estos atributos. En cambio, DataContext verificará los atributos de estos objetos cuando convertirá los árboles de expresión de linq en código SQL.
Ahora, para ver algunos ejemplos reales. He ejecutado estos en LinqPad, así que no se preocupe por el método extraño Dump(). He sustituido con Console.WriteLine para hacer que el código sea más fácil de entender para la gente que no sabe acerca de él :)
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;}
}
El resultado de la consola de este método es:
before class constructor
after class constructor
I am here. I'm the attribute constructor!
Custom: custm; Default: hello
y los Attribute.GetCustomAttributes(test.GetType())
devuelve esta matriz: (la tabla muestra todas las columnas disponibles para todas las entradas .. Así que no, el atributo Serializable no tiene estas propiedades :))
consiguió cualquier mor e preguntas? ¡Siéntete libre de preguntar!
UPD: Lo he visto hacer una pregunta: ¿por qué utilizarlos? Como ejemplo, le contaré sobre la biblioteca XML-RPC.NET. Crea su clase de servicio XML-RPC, con métodos que representarán los métodos xml-rpc. Lo principal en este momento es: en XmlRpc los nombres de los métodos pueden tener algunos caracteres especiales, como puntos. Entonces, puede tener un método flexlabs.ProcessTask() xml rpc.
Se podría definir esta clase de la siguiente manera:
[XmlRpcMethod("flexlabs.ProcessTask")]
public int ProcessTask_MyCustomName_BecauseILikeIt();
Esto me permite nombrar el método en la manera que me gusta, sin dejar de utilizar el nombre público, ya que tiene que ser.
+1 Todos para respuestas útiles. Ahora entiendo claramente que los atributos no tienen ningún comportamiento y no cambian el comportamiento de la clase a la que se aplican. Simplemente son metadatos extra anclados en una clase. Entonces, lo que percibí como "comportamiento" no era realmente el código de la clase de atributo, sino solo otro código, como el método Serialize, que interpreta los metadatos y los usa para realizar acciones condicionalmente (como un método Serialize que mira el atributo Serializable). – AaronLS
Vea un buen ejemplo de cuándo se ejecutan los constructores de atributos: http://stackoverflow.com/a/1168590/84206 – AaronLS