Mam klasę o nazwie Questions
(liczba mnoga). W tej klasie jest wyliczenie zwane Question
(liczba pojedyncza), które wygląda tak.
public enum Question
{
Role = 2,
ProjectFunding = 3,
TotalEmployee = 4,
NumberOfServers = 5,
TopBusinessConcern = 6
}
W Questions
klasie mam get(int foo)
funkcję, która zwraca do tego Questions
obiekt foo
. Czy istnieje prosty sposób na usunięcie wartości całkowitej z wyliczenia, aby móc zrobić coś takiego Questions.Get(Question.Role)
?
get(int foo)
którą można zdefiniować, aget(Question foo)
następnie wykonać rzutowanie wewnątrz metody, można wywołać metodę jakoQuestions.Get(Question.Role)
Odpowiedzi:
Wystarczy rzucić wyliczenie, np
Powyższe będzie działać dla ogromnej większości wyliczeń, które widzisz na wolności, ponieważ domyślnym rodzajem wyliczenia jest
int
.Jednak, jak wskazuje Cecilphillip , wyliczenia mogą mieć różne podstawowe typy. Jeśli enum jest zadeklarowana jako
uint
,long
lubulong
, powinno być oddane do typu wyliczenia; np. dlapowinieneś użyć
źródło
enum Test { Item = 1 }
i zobaczyć, że1 == (int)Test.Item
to jest równe.(int)Test.Item
That is cast! () jest jawnym operatorem rzutowania.enum Question
nie było,int
alelong
ta obsada obetnieRole
całkowitą wartość!Enum
parametr, wiesz, że możesz uzyskać tylko stałą liczbę możliwych wartości całkowitych. Z drugiej strony, jeśli weźmiesz po prostu anint
, musisz sprawdzić, czyint
mieści się w akceptowanych wartościach, co komplikuje kod. Zawsze możesz przesłonić swoje podpisy, takie jak: `` public void MyMethod (int x) {// zrób coś z x} public void MyMethod (Enum x) {this.MyMethod ((int) x); } ``Ponieważ wyliczenia może być dowolny integralną typu (
byte
,int
,short
, itd.), Bardziej wydajny sposób, aby uzyskać wartości bazowej całka wyliczenia byłoby skorzystać zGetTypeCode
metody w połączeniu zConvert
klasą:Powinno to działać niezależnie od podstawowego typu całki.
źródło
var
jest to typobject
, więc musisz go rozpakować, a robi się bałagan, niż bym chciał.object val = Convert...etc
navar
w swoim przykładzie zawsze będzieobject
.Zadeklaruj jako klasę statyczną o stałych publicznych:
A potem możesz odwołać się do niego jako
Question.Role
i zawsze będzie to ewaluacja doint
czegoś, co zdefiniujesz jako.źródło
static readonly int
ponieważ stałe są kompilowane do ich twardych wartości. Zobacz stackoverflow.com/a/755693/492const
a niestatic readonly
dlatego, że za każdym razem, gdy porównujeszstatic readonly
, wywołujesz metodę, aby uzyskać wartość zmiennej, podczas gdy zconst
porównujesz bezpośrednio dwa typy wartości.compilation limitation
mam na myśli to, że wartość jest zakodowana na stałe podczas kompilacji, więc każda zmiana tej wartości wymagałaby ponownej kompilacji wszystkich używających ją zestawów. Jestem skłonny zgodzić się z tobą na temat użytkowania, ponieważ zmiana wartości miałaby daleko idące konsekwencje.Spowoduje w
value == 2
.źródło
W powiązanej notatce, jeśli chcesz uzyskać
int
wartośćSystem.Enum
, podaje
tutaj:Możesz użyć:
Dwa ostatnie są po prostu brzydkie. Wolę pierwszy.
źródło
To łatwiejsze niż myślisz - wyliczenie to już int. Trzeba tylko przypomnieć:
źródło
Przykład:
A w kodzie z tyłu, aby uzyskać wartość wyliczenia:
lub
Wyliczenia będą zwiększane o 1 i możesz ustawić wartość początkową. Jeśli nie ustawisz wartości początkowej, początkowo zostanie przypisana jako 0.
źródło
1
zint
wyjątkiem jawnie zdefiniować inaczejNiedawno zrezygnowałem z używania wyliczeń w moim kodzie na rzecz zamiast używania klas z chronionymi konstruktorami i predefiniowanymi instancjami statycznymi (dzięki Roelof - C # Upewnij się, że Valum Enum Values - Futureproof Method ).
W związku z tym poniżej przedstawiam teraz ten problem (w tym niejawną konwersję do / z
int
).Zaletą tego podejścia jest to, że otrzymujesz wszystko, co miałbyś z wyliczenia, ale twój kod jest teraz znacznie bardziej elastyczny, więc jeśli musisz wykonywać różne działania w oparciu o wartość
Question
, możesz umieścić logikę wQuestion
sobie (tj. W preferowanym OO moda), w przeciwieństwie do umieszczania wielu instrukcji w całym kodzie w celu rozwiązania każdego scenariusza.NB: Odpowiedź zaktualizowana 27.04.2018, aby skorzystać z funkcji C # 6; tzn. wyrażenia deklaracyjne i definicje treści wyrażeń lambda. Zobacz historię zmian dla oryginalnego kodu. Ma to tę zaletę, że definicja jest nieco mniej szczegółowa; która była jedną z głównych skarg na podejście tej odpowiedzi.
źródło
Jeśli chcesz uzyskać liczbę całkowitą dla wartości wyliczonej, która jest przechowywana w zmiennej, dla której typ byłby
Question
, na przykład w metodzie, możesz po prostu zrobić to, co napisałem w tym przykładzie:Spowoduje to zmianę tytułu okna na 4, ponieważ zmienną
Geselecteerd
jestTalen.Nederlands
. Jeśli zmienię to naTalen.Portugees
i wywołam ponownie metodę, tekst zmieni się na 3.źródło
Aby upewnić się, że istnieje wartość wyliczenia, a następnie ją przeanalizować, możesz również wykonać następujące czynności.
źródło
Może mi tego brakowało, ale czy ktoś próbował prostej ogólnej metody rozszerzenia?
To działa świetnie dla mnie. W ten sposób można uniknąć rzutowania typu w interfejsie API, ale ostatecznie powoduje to operację zmiany typu. Jest to dobry przypadek do zaprogramowania Roslyn, aby kompilator stworzył dla ciebie metodę GetValue <T>.
źródło
Jeszcze jeden sposób, aby to zrobić:
Spowoduje to:
źródło
... to dobra deklaracja.
Musisz rzucić wynik na int tak:
W przeciwnym razie typ jest nadal
QuestionType
.Ten poziom ścisłości jest sposobem C #.
Jedną z możliwości jest użycie deklaracji klasy zamiast:
Deklarowanie jest mniej eleganckie, ale nie trzeba go umieszczać w kodzie:
Alternatywnie możesz czuć się bardziej komfortowo z Visual Basic, który zaspokaja tego rodzaju oczekiwania w wielu obszarach.
źródło
number
powinien mieć wartość2
.źródło
bool
*,byte
,ushort
,int
, iuint
**. GetHashCode dla innych typów modyfikuje wartość, np. Robi niektóre przesunięcia bitów i xory. (* 1/0, ** casted do int oczywiście). Ale w sumie nie rób tego, chyba że jest to twój prywatny kod.Możesz to zrobić, implementując metodę rozszerzenia do zdefiniowanego typu wyliczenia:
Upraszcza to uzyskanie wartości int bieżącej wartości wyliczenia:
lub
źródło
Zamiast tego użyj metody rozszerzenia:
A użycie jest nieco ładniejsze:
źródło
źródło
Posługiwać się:
Spowoduje to
value == 2
.Jest to prawdą tylko wtedy, gdy wyliczenie mieści się w
int
.źródło
int
oczywiście w środku , ponieważGetHashCode
zwraca liczbę całkowitą.Ponieważ wyliczenia można zadeklarować za pomocą wielu typów pierwotnych, użyteczna może być ogólna metoda rozszerzenia do rzutowania dowolnego typu wyliczenia.
źródło
Poniżej przedstawiono metodę rozszerzenia
źródło
Mój ulubiony hack z int lub mniejszymi wyliczeniami:
Dla wyliczenia
To,
wyjścia
Zrzeczenie się:
Nie działa na wyliczenia oparte na długim.
źródło
Najłatwiejszym rozwiązaniem jest przeciążenie
Get(int)
metody w ten sposób:gdzie
[modifiers]
ogólnie może być taki sam jak dlaGet(int)
metody. Jeśli nie możesz edytowaćQuestions
klasy lub z jakiegoś powodu nie chcesz, możesz przeładować metodę, pisząc rozszerzenie:źródło
Przykład, który chciałbym zasugerować „aby uzyskać wartość„ int ”z wyliczenia”, to
Teraz odpowiedź będzie wynosić 1.
źródło
Posługiwać się:
źródło
Wypróbuj ten zamiast konwersji enum na int:
źródło
W języku Visual Basic powinno to być:
źródło
Wymyśliłem tę metodę rozszerzenia, która obejmuje bieżące funkcje językowe. Korzystając z dynamiki, nie muszę robić z tego ogólnej metody i określać typ, który sprawia, że wywołanie jest prostsze i spójne:
źródło