Nazwa ciągu wyliczeniowego z wartości

407

Mam konstrukcję enum taką:

public enum EnumDisplayStatus
{
    None    = 1,
    Visible = 2,
    Hidden  = 3,
    MarkedForDeletion = 4
}

W mojej bazie danych wyliczenia są przywoływane przez wartość. Moje pytanie brzmi: jak mogę odwrócić reprezentację liczbową wyliczenia z powrotem do nazwy ciągu?

Na przykład biorąc 2pod uwagę wynik powinien być Visible.

jdee
źródło
25
Wierzę, że teraz jest łatwiejszy sposób, aby to zrobić w VS 2015 nameof(EnumDisplayStatus.Visible)Mam nadzieję, że to komuś pomaga
Gabriel Marius Popescu

Odpowiedzi:

542

Możesz przekonwertować intplecy na element członkowski wyliczenia za pomocą prostej rzutowania, a następnie wywołać ToString():

int value = GetValueFromDb();
var enumDisplayStatus = (EnumDisplayStatus)value;
string stringValue = enumDisplayStatus.ToString();
Kent Boogaart
źródło
13
Aktualizacja: tylko niektóre przeciążenia przy użyciu IFormatProvider są przestarzałe. ToString () jest w porządku. Zobacz groups.google.com/group/DotNetDevelopment/browse_thread/thread/…
AndyM
Jakie jest zachowanie w przypadku enum Foo { A = 1, B= 1 }?
dbkk
3
@dbkk dokumentacja stwierdza, że ​​w odniesieniu do wyliczeń „twój kod nie powinien przyjmować żadnych założeń dotyczących tego, który ciąg znaków zostanie zwrócony”. ze względu na dokładną sytuację, którą zacytowałeś. patrz msdn.microsoft.com/en-us/library/16c1xs4z.aspx
Paul D'Ambra
4
Zaktualizowane rozwiązanie: msdn.microsoft.com/en-us/library/…
Jack
4
krótszy: var stringValue = (wartość (EnumDisplayStatus)) .ToString ()
redwards510
188

Jeśli chcesz uzyskać ciąg "Visible"bez uzyskania EnumDisplayStatusinstancji, możesz to zrobić:

int dbValue = GetDBValue();
string stringValue = Enum.GetName(typeof(EnumDisplayStatus), dbValue);
algreat
źródło
5
Jeśli chodzi o odpowiedź Mandoleen, istnieje niedokładność: Enum.GetName zwraca ciąg, a nie Enum
algreat
Czy to wykorzystuje odbicie, czy też kompilator tworzy słownik pomocniczy do użycia za scenami?
palswim
155

Spróbuj tego:

string m = Enum.GetName(typeof(MyEnumClass), value);
Mandoleen
źródło
@ nilco ta odpowiedź jest dobra, ale wolę odpowiedź Kentsa, głównie dlatego, że mam niestandardowy atrybut w moich wyliczeniach „Opis” Następnie mam rozszerzenie wyliczenia, aby uzyskać opis - służy to do wyświetlenia na ekranie dla użytkownika.
Harag
60

Użyj tego:

string bob = nameof(EnumDisplayStatus.Visible);
James Cooke
źródło
9
Wymagane jest C # 6+.
Adam K Dean
10
@AZChad to świetna rzecz, aby wiedzieć, jasne; ale tak naprawdę nie ma zastosowania w scenariuszu PO, ponieważ wartości pochodzą z bazy danych (więc: środowisko uruchomieniowe, nie czas kompilacji, wartości)
Marc Gravell
22

możesz po prostu rzucić

int dbValue = 2;
EnumDisplayStatus enumValue = (EnumDisplayStatus)dbValue;
string stringName = enumValue.ToString(); //Visible

ah .. Kent mnie pobił :)

Hath
źródło
Teraz Kent otrzymuje przedstawiciela „pierwszej odpowiedzi”. Niezły Kent! : p
Matt Kocaj,
12

DB do C #

EnumDisplayStatus status = (EnumDisplayStatus)int.Parse(GetValueFromDb());

C # do DB

string dbStatus = ((int)status).ToString();

źródło
12

ROZWIĄZANIE:

int enumValue = 2; // The value for which you want to get string 
string enumName = Enum.GetName(typeof(EnumDisplayStatus), enumValue);

Ponadto użycie GetName jest lepsze niż jawne rzutowanie Enum .

[Kod testu wydajności]

Stopwatch sw = new Stopwatch (); sw.Start (); sw.Stop (); sw.Reset ();
double sum = 0;
int n = 1000;
Console.WriteLine ("\nGetName method way:");
for (int i = 0; i < n; i++) {
   sw.Start ();
   string t = Enum.GetName (typeof (Roles), roleValue);
   sw.Stop ();
   sum += sw.Elapsed.TotalMilliseconds;
   sw.Reset ();
}
Console.WriteLine ($"Average of {n} runs using Getname method casting way: {sum / n}");
Console.WriteLine ("\nExplicit casting way:");
for (int i = 0; i < n; i++) {
   sw.Start ();
   string t = ((Roles)roleValue).ToString ();
   sw.Stop ();
   sum += sw.Elapsed.TotalMilliseconds;
   sw.Reset ();
}
Console.WriteLine ($"Average of {n} runs using Explicit casting way: {sum / n}");

[Przykładowy wynik]

GetName method way:
Average of 1000 runs using Getname method casting way: 0.000186899999999998
Explicit casting way:
Average of 1000 runs using Explicit casting way: 0.000627900000000002
Naveen Kumar V.
źródło
2
To jest kopia 7-letniej odpowiedzi. Czy możesz wyjaśnić, dlaczego twój jest lepszy od oryginału?
nvoigt
@nvoigt Ponieważ, jeśli mam rację, API ToString () w Enum jest teraz przestarzałe. [ docs.microsoft.com/en-us/dotnet/api/…
Naveen Kumar V
Więc ... przynajmniej dwie inne odpowiedzi zawierają już opublikowany kod. Co oferuje twoje w porównaniu do tego z Mandoleen lub algreat?
nvoigt
@nvoigt Nie wspomnieli o jego wydajności w porównaniu do rzutowania jawnego. Czy to wystarczy, aby polubić moją odpowiedź? : p W każdym razie dziękuję, mam nadzieję, że to komuś pomoże. :)
Naveen Kumar V
Wydaje się, że mamy problem z komunikacją. Jesteś na urządzeniu mobilnym, a może nie przewinąłeś wystarczająco daleko w dół? Istnieją dwie dokładne kopie twojej odpowiedzi sprzed 7 lat. Wymieniłem nazwiska osób odpowiadających, więc powinny być łatwe do znalezienia. Jaka jest twoja odpowiedź, której nie było tu od co najmniej 7 lat?
nvoigt
9

Najszybsze rozwiązanie do kompilacji czasu z wykorzystaniem nameof wyrażeń .

Zwraca literał wyliczenia.

public enum MyEnum {
    CSV,
    Excel
}


string enumAsString = nameof(MyEnum.CSV)
// enumAsString = "CSV"

Uwaga:

  • Nie chcesz wymieniać wyliczenia dużymi literami, ale używasz go do wykazania rozróżniania wielkości liter nameof.
Zbierać
źródło
To powinna być odpowiedź.
Fan LinPy
@LinPyfan Cieszę się, że działa dobrze! Jest to stosunkowo nowy termin w porównaniu do daty PO.
Reap
4

Potrzebuję tylko:

string stringName = EnumDisplayStatus.Visible.ToString("f");
// stringName == "Visible"
Al3x_M
źródło
1
w większości przypadków jest to prawie identyczna z najlepszą odpowiedzią sprzed 10 lat; dodanie "f"specyfikatora jest dopracowane i może, ale nie musi być tym, czego chce dzwoniący (zależy to od tego, czego chcą): docs.microsoft.com/en-us/dotnet/standard/base-types/…
Marc Gravell
Nie zwracałem uwagi na datę ahah. Myślę, że dobrze jest zaktualizować trochę stare rozwiązanie takie jak to. Nie będę ostatnim, który otworzy tę stronę. I dziękuję za twoją precyzję! :)
Al3x_M
3

Aby uzyskać wartość ciągu [Nazwa]:

EnumDisplayStatus enumDisplayStatus = (EnumDisplayStatus)GetDBValue();
string stringValue = $"{enumDisplayStatus:G}"; 

Aby uzyskać wartość wyliczenia:

string stringValue = $"{enumDisplayStatus:D}";
SetDBValue(Convert.ToInt32(stringValue ));
Muhammad Aqib
źródło
Dlaczego nie tylko .ToString ()? „facepalm”
MeTitus
3

użyłem tego kodu podanego poniżej

 CustomerType = ((EnumCustomerType)(cus.CustomerType)).ToString()
Biddut
źródło
1

Wystarczy rzutować int na typ wyliczenia:

EnumDisplayStatus status = (EnumDisplayStatus) statusFromDatabase;
string statusString = status.ToString();
Lacop
źródło