2009-11-06 9 views
6

Questa domanda ha in testa per un po 'di tempo, mi dispiace se sembra soggettiva. Ci sono alcuni svantaggi nell'usare bool in proprietà pubbliche e costruttori per oggetti dati. Considera il seguente codice come esempio.Enumerazione di due membri rispetto al valore booleano

Uso bool:

public class Room 
{ 
    public string Name { get; set; } 
    public bool Bookable { get; set; } 

    public Room(string name, bool bookable); 
} 

e l'uso di questa classe

Room r = new Room ("101", true); 

Questo è opportunamente funzionale, v'è tuttavia un altro modo di attuarla:

Uso enum :

public enum BookingStatus 
{ 
    Bookable, 
    NotBookable 
} 

public class Room 
{ 
    public string Name { get; set; } 
    public BookingStatus Bookable { get; set; } 

    public Room(string name, BookingStatus bookable); 
} 

e l'utilizzo di questa classe

Room r = new Room ("101", BookingStatus.Bookable); 

Per me i due sembrano funzionalmente equivalente, ci sono alcuni vantaggi e svantaggi di ogni comunque:

  • Quando si impostano le proprietà del metodo Enum è più verbose (puoi dedurre l'uso dell'enum dal solo codice)
  • Le enumerazioni possono essere estese per supportare ulteriori stati (particolarmente utili per un'API)
  • Le enumerazioni richiedono una digitazione notevolmente maggiore (anche se la riduce notevolmente)
  • Le enumerazioni non possono essere utilizzate in condizionali (ad es. se (r.bookable)), anche se apprezzo questo è banale da risolvere.

Mi manca qualcosa, totalmente fuori dal marchio? Non sono sicuro del motivo per cui mi infastidisce così tanto, forse sono troppo ossessivo per il mio bene!

+0

Parere: questo sembra non è il miglior esempio - se si tratta di una vera domanda si/no, quindi i bool sono appropriati. Anche se dovresti nominare correttamente le tue proprietà secondo la convenzione (ad es. "IsBookable") - Un esempio migliore è una domanda non si o no, come per sesso o unità di misura, ecc. - anche se riconosci due stati (pollici vs cm, o maschi vs femmine), dovresti usare un enum, perché queste non sono assolutamente domande "si o no" (anche se potresti farle in domande si/no, non lo sono, e potrebbero essere tutte ampliato per supportare più stati). – BrainSlugs83

risposta

2

Nel suo libro Refactoring, Martin Fowler spiega perché pensa che le enumerazioni siano un odore di codice, e posso solo essere d'accordo. Nel tuo esempio, un approccio migliore sarebbe quello di fare una classe astratta in camera:

public abstract class Room 
{ 
    public string Name { get; set; } 

    public abstract bool Bookable { get; } 
} 

classi BookableRoom e NonBookableRoom allora si può fare derivati.

public class BookableRoom : Room 
{ 
    public override bool Bookable 
    { 
     get { return true; } 
    } 
} 

public class NonBookableRoom : Room 
{ 
    public override bool Bookable 
    { 
     get { return false; } 
    } 
} 
+0

Punto di forza, e un metodo che ho usato altrove dove. Presumo che questo non funzionerebbe molto bene con qualcosa come Entity Framework? Tuttavia, sarebbe sicuramente molto simile a qualcosa di simile a un elenco di SharePoint. –

+10

Perché affermi che questo è un approccio migliore? Per me sembra altrettanto crescente di complessità. Penso che il principio KISS sia appropriato qui. – nightcoder

+0

Il libro fornisce una descrizione completa :) –

5

Ih v'è alcuna possibilità che in futuro ci potrebbe essere più di le prime due opzioni, l'aggiunta di una terza opzione per un enum è un lavoro molto meno poi cambiando tutto bool a enum.

+0

Questo è quello che ha già detto nella sua risposta (secondo punto nella lista dei proiettili). –

+0

tranne per l'aspetto "piano per il futuro". – fforw

8

Semplicemente a causa della leggibilità e della comprensione del codice, andrò per enumerare anziché booleano.

Confronta BookingStatus.Bookable e true, ovviamente capirai di più leggendo BookingStatus.Bookable.

Analogamente a quanto detto da Fforw, in futuro potrebbe essere necessario aggiungere più opzioni, enum sarebbe più semplice da modificare.

+0

E riguardo la sicurezza del tipo? Un enum impedirebbe a qualsiasi vecchio valore booleano di cadere in un parametro enum. – weberc2

+1

Anche questo è meglio da mantenere. Le modifiche sono minori quando si utilizza enum se viene inventato un nuovo tipo di BookingStatus –

4

Per una proprietà sarei probabilmente d'accordo. In "Codice pulito", tuttavia, viene indicato (correttamente) che l'intento di nascondino di bool viene utilizzato come parametri.Ad esempio, un metodo di formattazione potrebbe essere simile:

public void Format(bool pBold, bool pItalic, bool pUnderline) 
{ ... } 

Quando ha chiamato questo appare come:

Format(true, false, true); 

Invece sarebbe molto più leggibile come:

public enum BOLD { BOLD, NOT_BOLD } 
public enum ITALIC { ITALIC, NOT_ITALIC } 
public enum UNDERLINE { UNDERLINE, NOT_UNDERLINE } 

public void Format(BOLD pBold, ITALIC pItalic, UNDERLINE pUnderline) 
{ ... } 

Che poi fa la chiamata simile:

Format(BOLD.BOLD, ITALIC.NOT_ITALIC, UNDERLINE.NOT_UNDERLINE); 

(Ricordare che questo è solo un esempio di come i parametri bool nascondono l'intento; . Ci sono modi probabilmente migliori per l'attuazione del codice di cui sopra)

Nel vostro caso particolare, notare la differenza tra i due costruttore chiama:

// enum; intent is clear 
Room r = new Room ("101", BookingStatus.Bookable); 

// bool; true what? 
Room r = new Room("101", true); 
+2

Inoltre, non è possibile inserire una variabile contenente il valore in grassetto in "corsivo" quando si usano enumerazioni. :) Digitare sicurezza. – weberc2

+0

'// stringa; "101" cosa? 'Aggiungi un paio di stringhe e ti trovi nella stessa posizione di un bool. Allora cosa fai? Guardi la definizione del metodo. – Stijn

+0

@Stijn Concordato. Non leggere una firma del metodo non è una scusa per non capire una firma del metodo. – Dan

Problemi correlati