Saltar al contenido

Cómo crear tus propios atributos personalizados en C#

En Visual Studio la forma más rápida y fácil de empezar con los atributos es con el Recorte de Atributos. Puedes escribir Atributo y pulsar Tab para que Visual Studio genere un fragmento de Atributo de muestra. Ese recorte de Atributos genera lo siguiente:

12345678910111213141516171819202122232425[System.AttributeUsage(AttributeTargets.All, Inherited =false, AllowMultiple =true)]sealedclassMyAttribute:Attribute{// Ver las directrices de atributos en // http://go.microsoft.com/fwlink/? LinkId=85236readonlystring positionalString;// Este es un argumento posicionalpublicMyAttribute(string positionalString){esto. positionalString = positionalString;// TODO: Implementar el código aquí arrojadoNotImplementedException();}publicstring PositionalString {get{return positionalString;}}// Este es un argumentpublicint NamedInt {get;set;}}

csharp

Cómo crear tus propios atributos personalizados en C#
Cómo crear tus propios atributos personalizados en C#

Esto genera una nueva clase que hereda de la clase Atributo. No es necesario que la clase termine con «Atributo» pero es una convención para ayudar a otros a entender su código.

Una cosa importante a tener en cuenta es que la clase tiene un atributo en sí mismo que hace tres preguntas.

  1. Objetivos de los atributos – ¿A qué tipo de elementos se puede aplicar este atributo? AttributeTargets es una lista que enumera los posibles objetivos disponibles.
  2. Heredado – Si aplicas este atributo a una clase llamada AnimalClass y heredas otra clase llamada DogClass de AnimalClass, ¿debería heredarse también este atributo?
  3. Permitir Múltiples – ¿Pueden establecerse múltiples instancias de este atributo en un solo elemento?

Una clase de Atributo puede aceptar parámetros de construcción requeridos, parámetros de construcción opcionales y múltiples sobrecargas de construcción, como casi cualquier otra clase en C#.

Usando un ejemplo similar al de los Atributos del C# de Jason Roberts: Power and Flexibility for Your Code course, podemos crear un atributo que cambie el color de una propiedad cuando se muestre en una aplicación de consola.

Modificaremos el fragmento original generado por Visual Studio para crear una clase de Atributo de Color.

12345678910[AttributeUsage(AttributeTargets.Property, Inherited =true, AllowMultiple =true)]sealedclassColorAttribute:Attribute{publicColorAttribute(ConsoleColor color = ConsoleColor.Cyan){ Color = color;}publicConsoleColor Color {get;}}

csharp

Esto permite a alguien usar [Color] o [Color(ConsoleColor.Red)] en una propiedad. Establece que el color por defecto es Cyan si no se añade ningún color al atributo cuando se utiliza.

Una cosa común que hace que la gente se tropiece con atributos personalizados es que son un proceso de dos pasos. El código anterior sólo nos permite establecer el atributo en una propiedad. Ahora necesitamos añadir lógica en otra parte de nuestra aplicación para usar nuestro nuevo atributo.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051// Primero aplicar nuestros nuevos atributos a las propiedades en una clase públicaDog{[Color(ConsoleColor. Rojo)]publicstring Nombre {get;set;}[Color]publicstring Raza {get;set;}publicint Edad {get;set;}// A continuación crear una clase para usar esas propiedadespublicstaticclassDogConsoleWriter{publicstaticvoidLine(Dog dog){var defaultColor = Console. ForegroundColor; Console.Write("Name: ");// Aquí el primer plano de la consola se establece en el color del atributo o en un color por defecto Console.ForegroundColor =GetPropertyColor(nameeof(Dog.Name))? ? defaultColor;;; Console.Write(nombre.del.perro); Console.ForegroundColor = defaultColor; Console.WriteLine(); Console.Write("Raza: "); Console.ForegroundColor =GetPropertyColor(nombre(Perro. Raza))?? defaultColor; Console.Write(perro.raza); Console.ForegroundColor = defaultColor; Console.WriteLine(); Console.Write("Edad: "); Console.ForegroundColor =GetPropertyColor(nameeof(Dog. Edad))?? defaultColor; Console.Write(dog.Age); Console.ForegroundColor = defaultColor; Console.WriteLine();}// Aquí está la parte más importanteprivatestatic ConsoleColor? GetPropertyColor(string propertyName){// Esto usa el reflejo de C#&apos para obtener el atributo si existePropertyInfo propertyInfo =typeof(Dog).GetProperty(propertyName);ColorAttribute colorAttribute =(ColorAttribute)Attribute. GetCustomAttribute(propertyInfo,typeof(ColorAttribute));// Si colorAttribute no es nulo, entonces existe un atributo de colorif(colorAttribute !=null){retorno de colorAttribute.Color;}returnnull;}}</pre>
csharp

Ahora una aplicación de la consola podría usar esta clase de manera similar:

12345DogConsoleWriter.Line(newDog{ Name="Astro", Breed="Newfoundland"});</pre ];
csharp

Veamos más de cerca el método GetPropertyColor donde se realizan los pasos más importantes.

Consola privada estáticaColor?GetPropertyColor(cadena propertyName){PropertyInfo propertyInfo = typeof(Dog).GetProperty(propertyName);ColorAttribute colorAttribute =(ColorAttribute)Attribute. GetCustomAttribute(propertyInfo,typeof(ColorAttribute));if(colorAttribute !=null){retorno colorAttribute.Color;}retorno nulo;}</pre
csharp

Este método acepta una cadena del nombre de la propiedad GetPropertyColor(cadena propertyName). La cadena se pasa usando el nombre del operador, nameof(Dog.Age), para proporcionar seguridad de tipo.

El nombre de la propiedad se utiliza en la primera línea del método para obtener la información de la propiedad para el tipo especificado. El tipo en nuestro caso es el tipo de perro. PropertyInfo propertyInfo = typeof(Dog).GetProperty(propertyName);

Una vez obtenida la PropertyInfo podemos comprobar si tiene algún atributo aplicado. Como sólo nos importa el Atributo de Color, especificamos ese tipo. ColorAttribute colorAttribute = (ColorAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(ColorAttribute));

GetCustomAttribute devolverá nulo si no puede encontrar un atributo.