Come utilizzare un'enumeration come attribute?
Nello snippet seguente mostro un semplice ma elegante pattern per il wrapping di un'enumeration (ho inserito le spiegazioni come commenti nel codice).
Il fatto che il wrapper deriva da System.Attribute è solo per offrire una situazione concreta in cui il wrapping diventa utile e necessario. Con il valore 0 per il primo elemento dell'enumeration ho voluto ricordare una best practice spesso dimenticata: "ensure that 0 is a valid state for value types" (vedi l'item 8 del libro "Effective C#" di Bill Wagner, oppure (aggiornamento 1: 06/07/05) la regola 10.9 nel libro di Balena e Dimauro).
using System;
public enum FooEnum
{
Something = 0, // Default
SomethingElse
}
public sealed class FooAttribute : Attribute
{
// il campo enumeration su cui si fa il wrapping
private readonly FooEnum _Foo;
public FooEnum Foo {get{return _Foo;}}
// private perché non è un elemento esplicito dell'enumeration
private static readonly FooAttribute _Default = FooAttribute.Something;
public static readonly FooAttribute Something = new FooAttribute(FooEnum.Something);
public static readonly FooAttribute SomethingElse = new FooAttribute(FooEnum.SomethingElse);
// l'enumeration ha un elemento di valore 0 (default)
public FooAttribute() : this(new FooEnum()) { }
public FooAttribute(FooEnum foo)
{
_Foo = foo;
}
public override bool IsDefaultAttribute()
{
return Equals(FooAttribute._Default);
}
public override bool Equals(object value)
{
if (value == this)
{
return true;
}
if (!(value is FooAttribute))
{
return false;
}
return (((FooAttribute)value).Foo == Foo);
}
// Equals e GetHashCode ridefiniti insieme, altrimenti warning CS0659
public override int GetHashCode()
{
return base.GetHashCode();
}
// ToString dell'enumeration
public override string ToString()
{
return Foo.ToString();
}
}
(Aggiornamento 2: 06/07/05) Ho visto solo adesso che avevo trattato lo stesso argomento anche in un altro post... :-)