Web Log di Adrian Florea

"You know you've achieved perfection in design, not when you have nothing more to add, but when you have nothing more to take away." Antoine de Saint-Exupery
posts - 440, comments - 2715, trackbacks - 3944

My Links

Archives

Post Categories

Image Galleries

.RO Blogs

.RO People

.RO Sites

Blogs

Furls

Links

vinCitori

Decorando con enum

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... :-)

Print | posted on martedì 5 luglio 2005 23:46 | Filed Under [ Carillon .NET Pattern Dappertutto ]

Powered by:
Powered By Subtext Powered By ASP.NET