una objetos metodos llamar extender ejemplos declaración crear como clases clase atributos c# attributes

c# - objetos - ¿Cómo funcionan las clases de atributos?



ejemplos de clases en c# (6)

Los atributos son esencialmente metadatos que se pueden adjuntar a varias partes de su código. Estos metadatos pueden entonces interogerse y afectar el comportamiento de ciertas operaciones.

Los atributos se pueden aplicar a casi todos los aspectos de su código. Por ejemplo, los atributos se pueden asociar en el nivel de ensamblaje, como los atributos AssemblyVersion y AssemblyFileVersion, que rigen los números de versión asociados con el ensamblaje.

[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]

Luego, el atributo Serializable, por ejemplo, se puede aplicar a una declaración de tipo para marcar el tipo como una serialización compatible. De hecho, este atributo tiene un significado especial dentro del CLR y en realidad se almacena como una directiva especial directamente sobre el tipo en el IL, esto se optimiza para ser almacenado como un indicador de bit que puede procesarse de manera mucho más eficiente, hay algunos atributos en Esta naturaleza, que se conocen como atributos pseudo personalizados.

Otros atributos se pueden aplicar a métodos, propiedades, campos, enumeraciones, valores de retorno, etc. Puede obtener una idea de los posibles destinos a los que se puede aplicar un atributo al consultar este enlace http://msdn.microsoft.com/en-us/library/system.attributetargets(VS.90).aspx

Además de esto, puede definir sus propios atributos personalizados que luego se pueden aplicar a los objetivos aplicables para los cuales están destinados sus atributos. Luego, en tiempo de ejecución, su código podría reflejar los valores contenidos en los atributos personalizados y tomar las medidas apropiadas.

Para un ejemplo bastante ingenuo, y esto es solo por el ejemplo :) Es posible que desee escribir un motor de persistencia que automáticamente asigne Clases a tablas en su base de datos y asigne las propiedades de la Clase a las columnas de la tabla. Podrías comenzar por definir dos atributos personalizados.

TableMappingAttribute ColumnMappingAttribute

Que luego puede aplicar a sus clases, como ejemplo tenemos una clase Person

[TableMapping("People")] public class Person { [ColumnMapping("fname")] public string FirstName {get; set;} [ColumnMapping("lname")] public string LastName {get; set;} }

Cuando esto se compila, aparte del hecho de que el compilador emite los metadatos adicionales definidos por los atributos personalizados, poco más se ve afectado. Sin embargo, ahora puede escribir un PersistanceManager que puede inspeccionar dinámicamente los atributos de una instancia de la clase Person e insertar los datos en la tabla Personas, asignando los datos en la propiedad FirstName a la columna fname y la propiedad LastName a la columna lname.

En cuanto a su pregunta sobre las instancias de los atributos, la instancia del atributo no se crea para cada instancia de su Clase. Todas las instancias de People compartirán la misma instancia de TableMappingAttribute y ColumnMappingAttributes. De hecho, las instancias de atributos solo se crean cuando realmente consulta los atributos la primera vez.

Mis búsquedas siguen apareciendo solo guías que explican cómo usar y aplicar atributos a una clase. Quiero aprender cómo crear mis propias clases de atributos y la mecánica de cómo funcionan.

¿Cómo se instancian las clases de atributos? ¿Se crean instancias cuando se crea una instancia de la clase a la que se aplican? ¿Se crea una instancia para cada clase a la que se aplica? Por ejemplo, si aplico la clase SerializableAttribute a una clase MyData, y si instalo 5 instancias MyData, ¿habrá 5 instancias de la clase SerializbleAttribute creadas detrás de escena? ¿O hay solo una instancia compartida entre todos ellos?

¿Cómo acceden las instancias de clase de atributo a la clase a la que están asociadas? ¿Cómo accede una clase SerializableAttribute a la clase a la que se aplica para que pueda serializar sus datos? ¿Tiene algún tipo de propiedad SerializableAttribute.ThisIsTheInstanceIAmAppliedTo? :) ¿O funciona en la dirección inversa que cada vez que serializo algo, la función Serialize a la que paso la instancia MyClass irá reflexivamente a través de los atributos y encontrará la instancia SerialiableAttribute?


No hay mucho tiempo para darle una respuesta más completa, pero puede encontrar los Atributos que se han aplicado a un valor utilizando Reflexión. En cuanto a crearlos, hereda de la Clase de atributo y trabaja desde allí, y los valores que proporciona con un atributo se pasan al constructor de la clase de Atributo.

Ha pasado un tiempo, como se podría decir ...

Martín


No he usado atributos en mi trabajo diario antes, pero he leído sobre ellos. También he hecho algunas pruebas, para respaldar lo que voy a decir aquí. Si me equivoco en cualquier lugar, no dude en decirme esto :)

Por lo que sé, los atributos no actúan como clases regulares. No se crean instancias cuando creas un objeto al que se aplican, no una instancia estática, no 1 por cada instancia del objeto. Tampoco acceden a la clase a la que se aplican.

En su lugar, actúan como propiedades (atributos?: P) de la clase. No como las propiedades de la clase .NET, más como en el tipo de propiedad "una propiedad del vidrio es la transparencia". Puede verificar qué atributos se aplican a una clase a partir de la reflexión, y luego actuar en consecuencia. Son esencialmente metadatos que se adjuntan a la definición de clase, no los objetos de ese tipo.

Puede intentar obtener la lista de atributos en una clase, método, propiedad, etc. Cuando obtenga la lista de estos atributos, aquí es donde se crearán las instancias. Entonces puedes actuar sobre los datos dentro de estos atributos.

Por ejemplo, las tablas Linq, las propiedades tienen atributos que definen a qué tabla / columna se refieren. Pero estas clases no usan estos atributos. En su lugar, el DataContext verificará los atributos de estos objetos cuando convertirá los árboles de expresión linq en código SQL.

Ahora para algunos ejemplos reales ... He ejecutado estos en LinqPad , así que no te preocupes por el extraño método Dump (). Lo he reemplazado con Console.WriteLine para que el código sea más fácil de entender para las personas que no lo saben :)

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 Attribute.GetCustomAttributes(test.GetType()) devuelve esta matriz: (la tabla muestra todas las columnas disponibles para todas las entradas. Entonces, el atributo Serializable no tiene estas propiedades :))

¿Alguna pregunta mas? ¡Siéntete libre de preguntar!

UPD: Te he visto hacer una pregunta: ¿por qué usarlos? A modo de ejemplo, les contaré acerca de la biblioteca XML-RPC.NET. Usted 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. Por lo tanto, puede tener un método flexlabs.ProcessTask () xml rpc.

Definirías esta clase de la siguiente manera:

[XmlRpcMethod("flexlabs.ProcessTask")] public int ProcessTask_MyCustomName_BecauseILikeIt();

Esto me permite nombrar el método de la manera que me gusta, mientras sigo usando el nombre público como debe ser.


Piense que los atributos son publicaciones posteriores que se adjuntan a las clases o definiciones de método (incrustadas en los metadatos del conjunto).

Luego puede tener un módulo de procesador / corredor / inspector que acepta estos tipos reflexionando, busca estos post-it y los maneja de manera diferente. Esto se llama programación declarativa. Usted declara algún comportamiento en lugar de escribir código para ellos en el tipo.

  • El atributo serializable en un tipo declara que está construido para ser serializado. El XmlSerializer puede entonces aceptar un objeto de esta clase y hacer lo necesario. Marque los métodos que necesitan ser serializados / ocultos con los post-it correctos.
  • Otro ejemplo sería la UNIT. El corredor NUnit examina los atributos [TestFixture] de todas las clases definidas en el ensamblaje de destino para identificar las clases de prueba. Luego busca métodos marcados con el atributo [Prueba] para identificar las pruebas, que luego ejecuta y muestra los resultados.

Es posible que desee ejecutar este tutorial en MSDN al que se responde la mayoría de sus preguntas junto con un ejemplo al final. Aunque podrían haber extraído un método llamado Audit(Type anyType); En lugar de duplicar ese código. El ejemplo ''imprime información'' inspeccionando atributos ... pero podría hacer cualquier cosa en el mismo sentido.


Sí, están instanciados con los parámetros que le das.

El atributo no "accede" a la clase. El atributo se adjunta a la lista de atributos de la clase ''/ propiedad en los datos de reflexión.

[Serializable] public class MyFancyClass { ... } // Somewhere Else: public void function() { Type t = typeof(MyFancyClass); var attributes = t.GetCustomAttributes(true); if (attributes.Count(p => p is SerializableAttribute) > 0) { // This class is serializable, let''s do something with it! } }


Si observa este código fuente abierto de descarga LINQ a Active Directory (CodePlex) , puede encontrar interesante el mecanismo del archivo Attributes.cs donde Bart De Smet ha escrito todas sus definiciones de clases de atributos. He aprendido atributos allí.

En resumen, puede especializar la clase de Attribute y codificar algunas propiedades especializadas para sus necesidades.

public class MyOwnAttributeClass : Attribute { public MyOwnAttributeClass() { } public MyOwnAttributeClass(string myName) { MyName = myName; } public string MyName { get; set; } }

y luego, puedes usarlo donde sea que MyOwnAttributeClass sea útil. Puede ser sobre una definición de clase o una definición de propiedad.

[MyOwnAttributeClass("MyCustomerName")] public class Customer { [MyOwnAttributeClass("MyCustomerNameProperty")] public string CustomerName { get; set; } }

Entonces, puedes conseguirlo a través de la reflexión así:

Attribute[] attributes = typeof(Customer).GetCustomAttribute(typeof(MyOwnAttributeClass));

Tenga en cuenta que el atributo que coloca entre corchetes es siempre el constructor de su atributo. Por lo tanto, si desea tener un atributo parametrizado, debe codificar su constructor como tal.

Este código se proporciona tal como está y puede no compilarse. Su propósito es darte una idea de cómo funciona.

De hecho, generalmente desea tener una clase de atributo diferente para una clase que para una propiedad.

¡Espero que esto ayude!