2009-07-22 8 views
54

Mam klasy z właściwością, która jest ENUMwartość początkowa enum

wyliczenia jest

/// <summary> 
/// All available delivery actions 
/// </summary> 
public enum EnumDeliveryAction 
    { 
    /// <summary> 
    /// Tasks with email delivery action will be emailed 
    /// </summary> 
    Email, 

    /// <summary> 
    /// Tasks with SharePoint delivery action 
    /// </summary> 
    SharePoint 
    } 

Kiedy utworzyć instancję tej klasy, nigdzie w kodzie, mogę podać wartość pola wyliczeniowego, ale wydaje się domyślna dla pierwszego elementu na liście wyliczeniowej, a nie wartość zerowa, to w jaki sposób działają wyliczenia? Jak to możliwe, aby upewnić się, że enum ma jakąś wartość pustą, jeśli nie jest ustawiony, nie chcę, aby domyślnie do pierwszej wartości w wyliczeniu.

+0

Enum jest typ wartości, w przeciwieństwie do typu odniesienia. Typy referencji będą domyślnie wartościami null, natomiast typy wartości będą domyślnie wartością. To znaczy. int domyślnie jest 0, data domyślna jest datą minimalną, itp. – contactmatt

Odpowiedz

103

Domyślną wartością dla enum typów jest 0 (który jest domyślnie pierwszym elementem w wyliczeniu). Pola klasy zostaną zainicjowane do wartości domyślnej.

Jeśli potrzebujesz do reprezentowania nieznaną wartość wyliczenia, można dodać element Unknown o wartości 0. Alternatywnie, można zadeklarować boiska Nullable<MyEnum> (MyEnum?).

+0

Czy muszę więc najpierw wyliczyć pierwszą wartość z 1? –

+0

Zaktualizowano odpowiedź, aby to odzwierciedlić. –

+1

Nie, chyba że chcesz, aby wartość domyślna była nieokreślona.. Nadal będzie ustawiona wartość zero, która, jeśli twoje wyliczenie nie ma członka o wartości zero, będzie wartością niedozwoloną .. –

8

Wyliczenia są typem wartości, np. Ints. Musisz uczynić go zerowalnym, aby nie był domyślnym pierwszym (lub zdefiniowanym przez 0) członkiem enum.

public class MyClass 
{ 
    public EnumDeliveryAction? DeliveryAction { get; set;} 
} 
+1

lub dodaj niezdefiniowanego członka: publiczna enum EnumDeliveryAction {Undefined = 0, Email = 1, Sharepoint = 2} –

+0

Możesz również użyć Nullable – Polaris878

+1

Polaris: 'Nullable ' jest identyczne z 'T?'. –

7

Pola enum są inicjalizowane jako zero; a jeśli nie określisz wartości w wyliczeniu, zaczynają się od zera (Email = 0, SharePoint=1 itd.).

Zatem domyślnie każde zainicjowane pole będzie Email. W takich przypadkach stosunkowo często dodaje się None=0 lub alternatywnie można użyć Nullable<T>; tj

/// <summary> 
/// All available delivery actions 
/// </summary> 
public enum EnumDeliveryAction 
{ 
    /// <summary> 
    /// Not specified 
    /// </summary> 
    None, 

    /// <summary> 
    /// Tasks with email delivery action will be emailed 
    /// </summary> 
    Email, 

    /// <summary> 
    /// Tasks with SharePoint delivery action 
    /// </summary> 
    SharePoint 
} 

Należy również upewnić się, aby nie traktować ostatnią oczekiwaną wartość jako domyślny; tj

switch(action) { 
    case EnumDeliveryAction.Email; RunEmail(); break; 
    default: RunSharePoint(); break; 
} 

powinno być:

switch(action) { 
    case EnumDeliveryAction.Email; RunEmail(); break; 
    case EnumDeliveryAction.SharePoint; RunSharePoint(); break; 
    default: throw new InvalidOperationException(
      "Unexpected action: " + action); 
} 
0

Tradycyjny aproach dodaniem null do wartości, które zazwyczaj nie mają jeden jest zadeklarować zmienną jako typ wartości pustych, tj:

EnumDeliveryAction? action=null; 
0

Sugerowałbym, aby jako pierwszą wartość wyliczenia była wybrana wartość None = 0. Uczyń to jasno, a potem na pewno wiesz, jaka jest wartość.

1

Możesz rozpocząć swoje wyliczenia na dowolną wartość (np. 1), ale gdy reprezentują one wartość odnośnika w bazie danych, zazwyczaj chcesz, aby pasowały do ​​siebie.

Generalnie deklaruję pierwszy Enum jako None (= 0), gdy ma to sens, zgodnie z wytycznymi programu .Net Framework Design.

6

Najlepsza praktyka (zgodnie z zaleceniami analizy kodu) polega na tym, aby zawsze mieć wartość domyślną w swoich wyliczeniach, które reprezentują wartość nieustawioną.

więc w Twoim przypadku, możesz mieć:

public enum EnumDeliveryAction 
    { 

    /// <summary> 
    /// Default value 
    /// </summary> 
    NotSet, 

    /// <summary> 
    /// Tasks with email delivery action will be emailed 
    /// </summary> 
    Email, 

    /// <summary> 
    /// Tasks with SharePoint delivery action 
    /// </summary> 
    SharePoint 
    } 

Tak na marginesie, nie należy poprzedzić nazwę wyliczenia z Enum. Możesz rozważyć zmianę na:

public enum DeliveryAction; 
+0

Nie jestem tak pewny, że zgadzam się z dodaniem "niezdefiniowanego" członka enum w .Net, ponieważ z definicji jest to wartość null - nieznana. Wydaje się zbędne, aby przedefiniować wartość zerową w każdym wyliczeniu, które tworzysz. –

+1

Wydaje mi się, że posiadanie wartości domyślnej w twoim wyliczeniu jest o wiele lepszą praktyką niż używanie wyrażeń zerujących. – Tim

0

Domyślnie tylko typy referencyjne są typu zerowalnego. Jeśli chcesz, aby zmienna zezwalała na wartości null, musisz zdefiniować ją jako zerowalną za pomocą znaku "?" postać (do tego potrzebujesz C# 2.0 lub więcej).

enum MyEnum 
{ 
    ValueOne, 
    ValueTwo 
} 

aw swojej klasie

MyEnum? myvariable = null; 
+0

Myślę, że masz na myśli to, że tylko * typy referencyjne * są domyślnie zerowe, ponieważ zarówno typy odniesienia, jak i wartości są uważane za obiekty w .NET – PatrickJ

+0

ye, to co miałem na myśli: D –

3

wyliczenia są typy wartości. typy wartości nie mogą być puste i są inicjowane na 0.

Nawet jeśli enum nie posiada 0, zmienne enum zostaną zainicjowane 0.

public enum SomeEnum 
{ 
    A = 1, 
    B = 2 
} 

(później)

SomeEnum x = default(SomeEnum); 
Console.WriteLine(x); 

wyjścia - 0


Niektóre Główni odpowiadający opowiadają za pomocą Nullable<T> pasujące do Twojego I oczekiwania nitryfikacyjne. Utrzymanie tej porady od Nullable<T> jest nadal typem wartości i ma inną semantykę niż typy referencyjne. Na przykład nigdy nie wygeneruje wyjątku odwołania zerowego (nie jest to odwołanie).

SomeEnum? x = default(SomeEnum?); 

if (x == null) 
{ 
    Console.WriteLine("It's null!"); 
} 
if (x > SomeEnum.B) 
{ 
} 
else 
{ 
    Console.WriteLine("This runs even though you don't expect it to"); 
} 
0

Moje C++ nauczyciel w szkole (11 lat temu) powiedział mi, że łącznik zastępuje enum z ich rzeczywistego typu:

typedef static const int enum;

ten sposób, za każdym razem piszesz coś takiego enum MY_VAL = 5;, można łatwo zastąpić static const int MY_VAL = 5; (ale to tylko sprawia, że ​​twój kod dłużej ...).

Zresztą, domyślna wartość każdej int 0.