2017-08-02 55 views
9

Mam klasy bazowej i kilka klas pochodnych od niego.C# jak napisać abstrakcyjną metodę, która zwraca enum

Chcę zadeklarować element wyliczeniowy w klasie bazowej jako abstrakcyjny, a każda klasa, która pochodzi z niego, będzie musiała utworzyć własne wyliczenie.

Jak mogę to zrobić?

Próbowałem następujące: Oświadczam abstrakcyjną metodę w klasie bazowej, które zwracają typ enum a każda klasa implementujące powróci własną ENUM:

public abstract enum RunAtOptions(); 

Ale otrzymuję błąd kompilacji

"The modifier abstract is not valid for this item" 
+0

enum jest typ i nie można mieć abstrakcyjne typy ... –

+4

Istnieją sposoby, aby emulować to, ale podejrzewam, że nie zrobić naprawdę tego potrzebuję, wygląda na [XY Problem] (http://xyproblem.info/). –

+0

Masz na myśli, że chcesz zmienić wyliczenie na podstawie klasy pochodnej? Więc generics? – DavidG

Odpowiedz

5

trzeba powrócić rzeczywista nie ENUM słowa kluczowego enum więc jeśli miał enumMyEnumType takiego:

public enum MyEnumType 
{ 
    ValueOne = 0, 
    ValueTwo = 1 
} 

public abstract MyEnumType RunAtOptions(); 

Jeżeli chcesz zmodyfikować, aby używać rodzajowych można mieć zwrot metoda T i mają ograniczenie do T struct:

public abstract T RunAtOptions() where T : struct; 

C# nie posiada ograniczenie rodzajowych wspierania enum rodzaj.

+0

Tak, ale "MyEnumType" jest problemem do rozwiązania. –

+1

Edytowano odpowiedź, aby wyświetlić definicję wyliczenia. –

+2

_ "i każda klasa, która pochodzi z tego, będzie musiała utworzyć własne wyliczenie" _ –

1

Nie można użyć słowa kluczowego enum jako członka abstrakcyjnego.Similar question

Ewentualnie można wprowadzić właściwość słownika abstrakcyjnego.

public class Base 
{ 
    public abstract Dictionary<string, int> RunAtOptions { get; } 
} 

Klasa pochodna może ustawić właściwość w konstruktorze.

public class Derived : Base 
{ 
    public override Dictionary<string, int> RunAtOptions { get; } 

    public Derived() 
    { 
     RunAtOptions = new Dictionary<string, int> 
     { 
      ["Option1"] = 1, 
      ["Option2"] = 2 
     } 
    } 
} 

Niestety, zastosowanie tej metody nie zapewni eleganckich kontroli podczas kompilacji. Z tego słownika można porównać wartości opcji przed wpisów w słowniku tak:

if (someObject.Options == RunAtOptions["Option1"]) // someObject.Options is of type `int` 
{ 
    // Do something 
}