Metody wewnątrz wyliczenia w języku C #

165

W Javie możliwe jest umieszczenie metod wewnątrz wyliczenia.

Czy w C # jest taka możliwość, czy jest to tylko zbiór ciągów i to wszystko?

Próbowałem zastąpić, ToString()ale to się nie kompiluje. Czy ktoś ma prosty przykład kodu?

Eya
źródło
Nie sądzę, aby można było mieć metody wewnątrz Enum w C #. Co próbujesz zrobić?
Duncan Howe
próbując uzyskać zachowanie Javy i hermetyzować zamkniętą logikę w Enums. zresztą widzę z odpowiedzi, że to niemożliwe - zaimplementuję rozszerzenia.
Eya

Odpowiedzi:

272

Możesz pisać metody rozszerzające dla typów wyliczeniowych:

enum Stuff
{
    Thing1,
    Thing2
}

static class StuffMethods
{

    public static String GetString(this Stuff s1)
    {
        switch (s1)
        {
            case Stuff.Thing1:
                return "Yeah!";
            case Stuff.Thing2:
                return "Okay!";
            default:
                return "What?!";
        }
    }
}

class Program
{


    static void Main(string[] args)
    {
        Stuff thing = Stuff.Thing1;
        String str = thing.GetString();
    }
}
MarkPflug
źródło
11

Inną opcją jest użycie klasy wyliczenia stworzonej przez Jimmy'ego Bogarda .

Zasadniczo musisz stworzyć klasę, która dziedziczy po jego Enumeration. Przykład:

public class EmployeeType : Enumeration
{
    public static readonly EmployeeType Manager 
        = new EmployeeType(0, "Manager");
    public static readonly EmployeeType Servant 
        = new EmployeeType(1, "Servant");
    public static readonly EmployeeType Assistant
        = new EmployeeType(2, "Assistant to the Regional Manager");

    private EmployeeType() { }
    private EmployeeType(int value, string displayName) : base(value, displayName) { }

    // Your method...
    public override string ToString()
    {
        return $"{value} - {displayName}!";
    }
}

Następnie możesz użyć go jak wyliczenia, z możliwością umieszczenia w nim metod (między innymi):

EmployeeType.Manager.ToString();
//0 - Manager
EmployeeType.Servant.ToString();
//1 - Servant
EmployeeType.Assistant.ToString();
//2 - Assistant to the Regional Manager

Możesz go pobrać za pomocą NuGet .

Chociaż ta implementacja nie jest natywna w języku, składnia (konstrukcja i użycie) jest bardzo zbliżona do języków, które implementują wyliczenia natywnie lepiej niż C # ( na przykład Kotlin ).

fabriciorissetto
źródło
3

Nie. Możesz utworzyć klasę, a następnie dodać kilka właściwości do klasy, aby w pewnym stopniu emulować wyliczenie, ale to nie to samo .

class MyClass
{
    public string MyString1 { get{ return "one";} }
    public string MyString2 { get{ return "two";} }
    public string MyString3 { get{ return "three";} }

    public void MyMethod()
    {
        // do something.
    }
}

Lepszym wzorcem byłoby umieszczenie metod w klasie innej niż emum.

Kyle Trauberman
źródło
0

Ponieważ natknąłem się i potrzebowałem dokładnego przeciwieństwa wyliczenia do ciągu, oto rozwiązanie ogólne:

static class EnumExtensions {
    public static T GetEnum<T>(this string itemName) {
        return (T) Enum.Parse(typeof(T), itemName, true);
    }
}

To również ignoruje wielkość liter i jest bardzo przydatne do analizowania odpowiedzi REST w wyliczeniu, aby uzyskać większe bezpieczeństwo typów. Mam nadzieję, że to komuś pomoże

scrat84
źródło
-15

C # nie zezwala na używanie metod w modułach wyliczających, ponieważ nie jest to zasada oparta na klasach, ale raczej dwuwymiarowa tablica z ciągiem i wartością.

Microsoft zdecydowanie odradza używanie klas w tym przypadku, zamiast tego użyj (data) struct (ures); STRUCT jest lekką klasą dla danych i ich procedur obsługi i może dobrze obsługiwać funkcje. C # i jego kompilator nie mają możliwości śledzenia i wydajności, jakie znamy z JAVA, gdzie im więcej razy dana klasa / metoda jest używana, tym szybciej działa i jej użycie staje się „oczekiwane”. C # po prostu tego nie ma, więc aby odróżnić, użyj STRUCT zamiast CLASS.

user236800
źródło
7
Siedem głosów przeciw bez ani jednego komentarza, aby wyjaśnić, co powinno być nie tak z tą odpowiedzią? No dalej ...
Good Night Nerd Pride
Czy wszystkie informacje podane w tym poście są błędne?
VK,
5
Ta część jest prawdziwa: C # nie zezwala na użycie metod w modułach wyliczających. Nie jestem jednak pewien, czy rozumowanie jest poprawne, a drugi akapit wydaje się całkowicie nieistotny dla pytania. Jeśli istnieje sposób na użycie struktury do symulacji wyliczenia z zachowaniem, najlepiej podać przykład.
Mishelle
3
Myślę, że konsekwencje są tutaj dość jasne. Nie zastępuj wyliczenia (który jest typem wartości) klasą (która jest typem referencyjnym) tylko po to, aby dodać metody, ponieważ struktury mogą również mieć metody i są również typami wartości.
smelch