2013-05-14 10 views
16

Mam klasy z właściwości enum tak:Jak sprawdzić, czy została ustawiona właściwość enum? C#

public class Foo 
{ 
    public Color ColorType {get;set;} 
} 

public enum Color 
{ 
    Red, 
    Green, 
} 

Teraz ta klasa może zostać zainicjowane tak:

var foo = new Foo(); 

bez właściwości ColorType kiedykolwiek jest ustawiony. Teraz Próbuję utworzyć metody i wykonywać czynności na enum czy kiedykolwiek ustawione czy nie, na przykład mam metodę

private void checkEnum(Foo foo) 
{ 
    if(foo.ColorType !=null) 
    { 
     //perform these actions 
    }else 
    { 
     //perform those actions 
    } 
} 

jednak otrzymuję ostrzeżenie mówiąc, że wartość nigdy nie będzie nieważne i po dalszych badaniach, jeśli wyliczenie nigdy nie zostanie ustawione, jeśli domyślnie ustawiona jest pierwsza wartość, która w moim przypadku byłaby Czerwona, myślałem o dodaniu wartości do mojego wyliczenia, która byłaby "nie ustawiona" i uczynienie tej wartości pierwszą wartością , więc jeśli nie został ustawiony, to enum będzie miało wartość "not set", czy jest lepszy sposób na zrobienie tego, moja proponowana metoda wydaje się być niechlujna

+0

Powinieneś umieć znaleźć odpowiedź tutaj: http://stackoverflow.com/questions/4967656/what-is-the-default-value-for-enum-variable –

Odpowiedz

26

Można użyć jednej z dwóch metod: domyślnej wartości wyliczeniowej lub wyliczenia zerowalnego.

Domyślna wartość enum

Ponieważ enum jest wspierany przez liczbę całkowitą, a int domyślnie zero, enum zawsze zainicjować domyślnie do wartości stanowiącej równowartość zera. Jeśli nie zostanie wyraźnie przypisana wartość wyliczana, pierwsza wartość będzie zawsze wynosić zero, druga będzie równa jeden i tak dalej.

public enum Color 
{ 
    Undefined, 
    Red, 
    Green 
} 

// ... 

Assert.IsTrue(Color.Undefined == 0); // success! 

Nullable enum

Innym sposobem radzenia sobie obsadzony enum jest użycie pola pustych.

public class Foo 
{ 
    public Color? Color { get; set; } 
} 

// ... 

var foo = new Foo(); 
Assert.IsNull(foo.Color);  // success! 
+1

Dobra odpowiedź, ale nie rozwiązuje problemu, że użytkownik jest w stanie aby ustawić wartość na wartość null lub undefined, a tym samym nie wiesz, czy użytkownik ustawił to w wyliczeniu, czy też wyliczenie nie uległo zmianie. –

+1

@MrUniverse true, można wprowadzić pole flagi binarnej, które jest ustawione przy pierwszej zmianie wartości 'Kolor'. Trzeba jednak uważać i upewnić się, że klasa nie jest nigdy zserializowana w sposób, który czyni ją fałszywą pozytywną. –

+0

Co jeśli był to atrybut taki jak "[UserModifiedMonitor]", który zostanie ustawiony na wartość true, gdy wywoływacz zostanie wywołany? Nie sądzę, że atrybuty są zawsze przekształcane w szereg z klasą. –

0

enum to typ wartości, więc nie może mieć wartości null, a pamięć jest ogólnie liczbą całkowitą. Jeśli chcesz niezdefiniowanej wartości dla danego typu może być

public enum Color 
{ 
    Undefined, 
    Red, 
    Green, 
} 
0

Jak odkryłem, wyliczenia w C# są typy wartości (są zasadniczo całkowite) nie odwołać typów, więc nie będzie domyślnie NULL ale raczej najniższa liczba całkowita w wyliczeniu. Nie trać z oczu tego związku, gdy zajmujesz się wyliczeniami, ponieważ jest to jedna z ich najbardziej użytecznych cech. Zawsze należy pamiętać, że to, czy jednoznacznie stwierdzić, czy nie,

public enum Color 
{ 
    Red, 
    Green 
} 

równa się:

public enum Color 
{ 
    Red = 0, 
    Green = 1 
} 

Choć można oczywiście dać każdemu członkowi wyliczenie dowolną wartość całkowitą, która Ci się podoba.

miarę czy istnieje lepszy sposób w ten sposób, to naprawdę wszystko zależy od tego, co „to” jest, choć nie ma nic złego z sugestią prostu stosując następującą konfigurację ENUM:

public enum Color 
{ 
    None = 0, 
    Red, 
    Green 
} 

Ogólnie rzecz biorąc, chcesz używać wyliczeń, gdy masz zdecydowanie skończony i dyskretny zestaw możliwych wartości, które chcesz mieć możliwość wyboru według nazwy. Na przykład powiedzmy, że mam metodę, która przyjmuje jeden z czterech głównych kierunków (północ, wschód, południe, zachód) jako parametr. Postanawiam, że chcę numerować każdy z kierunków zgodnie z ruchem wskazówek zegara, zaczynając od 0 dla Północy.

public enum Direction 
{ 
    North = 0, 
    East, 
    South, 
    West 
} 

Teraz, zamiast wziąć moja funkcja parametru całkowitą i ufając, że będę pamiętać co każdy numer odnosi się do, mogę teraz mieć funkcja ma człon wyliczenia jako parametr i od razu wiedzieć, w jakim kierunku mam z którym mam do czynienia. Na przykład:

getNeighbor(1); 

czyta dużo łatwiejsze, jak:

getNeighbor(Direction.East); 
1

wyliczenia są Value Types, co oznacza, że ​​nie są odniesienia do obiektu przechowywane gdzieś indziej, a zatem nie mogą być null.Zawsze mają one domyślną wartość, taką jak int, która domyślnie będzie równa zero podczas tworzenia. Proponuję dwa podejścia:

  1. dodać kolejny wpis enum nazwie np None o wartości równej zero. W ten sposób twoja wartość wyliczeniowa będzie domyślnie ustawiona na None. Następnie możesz sprawdzić if(foo.ColorType != Color.None).

  2. Złóż swoją właściwość Color jako wartość zerową taką jak: public Color? ColorType { get; set; }. Teraz domyślnie będzie to null i można mu przypisać wartość null. Przeczytaj więcej o typach nullable tutaj: MSDN - Nullable Types (C#).

2

Masz dwie prawdziwe opcje. Pierwszym z nich jest dodanie niezdefiniowanej wartości do wyliczenia. Będzie to wartość domyślna przed zainicjalizowaniem właściwości.

1)

public enum Color 
{ 
    Undefined, 
    Red, 
    Green, 
} 

z czekiem jak:

private void checkEnum(Foo foo) 
{ 
    if(foo.ColorType == Color.Undefined) 
    { 
     //perform these actions 
    }else 
    { 
     //perform those actions 
    } 
} 

2) Ewentualnie nie można dodać wartość niezdefiniowana i po prostu zrobić właściwość Nullable

public class Foo 
{ 
    public Color? ColorType {get;set;} 
} 
public enum Color 
{ 
    Red, 
    Green, 
} 

i wykonać twój czek:

private void checkEnum(Foo foo) 
{ 
    if(!foo.ColorType.HasValue) 
    { 
     //perform these actions 
    }else 
    { 
     //perform those actions 
    } 
} 
5

Można sprawić, aby ukryte prywatne pole było puste, ale właściwość nie jest.

E.g.

class SomeClass 
{ 
    private Color? _color; // defaults to null 

    public Color Color 
    { 
     get { retrun _color ?? Color.Black; } 
     set { _color = value; } 
    } 

    public bool ColorChanged 
    { 
     get { return _color != null; } 
    } 
} 

ten sposób, jeśli kolor == null wiesz, że to nie zostało jeszcze ustalone i są również zatrzymanie użytkownikowi ustawienie go null (lub undefined jak inne odpowiedzi określić). Jeśli color jest null masz 100% pewności, że użytkownik nie ustawił go nigdy.

Tylko catch jest wartością domyślną zwracaną przez get, ale zawsze można podać wyjątek, jeśli lepiej pasuje do twojego programu.

Można także wziąć go o krok dalej, co czyni go tak, że set tylko ustawia pole jeżeli dana wartość nie jest równa wartości domyślnej (w zależności od przypadku użycia):

public Color Color 
{ 
    get { retrun _color ?? Color.Black; } 
    set 
    { 
     if (value != Color) 
     { 
      _color = value; 
     } 
    } 
} 
+0

Możesz nawet zrobić "kolor powrotu" ?? Color.Black'. – Moira

+0

@ 1blustone Dzięki, poprawiono i wprowadzono ogólne poprawki odpowiedzi. –

Powiązane problemy