kurze Antwort, ja. In diesem speziellen Fall möchten Sie vielleicht die Verwendung vonTimeSpan
Jodrell
1
Die Verwendung von Erweiterungsmethoden für eine Aufzählung würde mich schmutzig machen. Erstellen Sie eine Klasse, um zu kapseln, was benötigt wird. Halten Sie eine Aufzählung so einfach wie möglich. Wenn Sie mehr Logik benötigen, erstellen Sie eine Duration-Klasse, die Tag, Woche, Monat plus verfügbar macht und jede andere Logik enthält, die in der Erweiterungsmethode enthalten gewesen wäre.
Jason Evans
2
Ich mag Enum-Erweiterungsmethoden für Flag-Gruppen. Ich ziehe es in , wenn Klauseln zum Beispiel Day.IsWorkday()über (Day & Days.Workday) > 0mit Days.Workdaydefiniert Monday | Tuesday ... | Friday. Ersteres ist meiner Meinung nach klarer und hat genau Letzteres umgesetzt.
Erweiterungsmethoden bieten eine Möglichkeit, Methoden für vorhandene Klassen so zu schreiben, wie andere Personen in Ihrem Team sie möglicherweise tatsächlich entdecken und verwenden. Angesichts der Tatsache, dass Aufzählungen Klassen wie jede andere sind, sollte es nicht allzu überraschend sein, dass Sie sie erweitern können, wie zum Beispiel:
Ich denke, Aufzählungen sind im Allgemeinen nicht die beste Wahl, aber zumindest können Sie so einen Teil des Schalters / der Handhabung zentralisieren und ein wenig abstrahieren, bis Sie etwas Besseres tun können. Denken Sie daran, zu überprüfen, ob die Werte ebenfalls im Bereich liegen.
Weitere Informationen finden Sie hier bei Microsft MSDN.
Ich glaube, der Kommentar "Aufzählungen sind böse" ist fehl am Platz, hat aber eine Grundlage in der Realität. Ich finde, dass Aufzählungen ein Problem sein können, das überbeansprucht wird, da sie Sie irgendwie an bestimmte Kontexte und Verhaltensweisen binden.
Ed Schwehm
1
Aufzählungen in C # saugen irgendwie, weil dies kompiliert und ausgeführt wird:Duration d = 0;
Graham
16
Given that enums are classesNein, sie sind keine Klassen.
Flügelspieler Sendon
1
Ich verwende diese Art der Erweiterung nur, wenn es direkt um die Aufzählung geht, wie Wochentage und Erweiterungsmethoden IsWeekday (), IsWeekendday (). Klassen sollen jedoch Verhaltensweisen kapseln. Wenn also viele oder komplizierte Verhaltensweisen gekapselt werden müssen, ist eine Klasse wahrscheinlich besser. Wenn es begrenzt und einfach ist, finde ich persönlich Erweiterungen für Aufzählungen in Ordnung. Wie bei den meisten Entwurfsentscheidungen gibt es unscharfe Grenzen zwischen Auswahlmöglichkeiten (IMO). Es ist erwähnenswert, dass Erweiterungen nur für statische Klassen der obersten Ebene und nicht für verschachtelte Klassen durchgeführt werden können. Wenn Ihre Aufzählung Teil einer Klasse ist, müssen Sie eine Klasse erstellen.
FreeText
51
Sie können dem Aufzählungstyp auch eine Erweiterungsmethode anstelle einer Instanz der Aufzählung hinzufügen:
/// <summary> Enum Extension Methods </summary>/// <typeparam name="T"> type of Enum </typeparam>publicclassEnum<T>where T :struct,IConvertible{publicstaticintCount{get{if(!typeof(T).IsEnum)thrownewArgumentException("T must be an enumerated type");returnEnum.GetNames(typeof(T)).Length;}}}
Sie können die oben beschriebene Erweiterungsmethode aufrufen, indem Sie Folgendes tun:
var result =Enum<Duration>.Count;
Es ist keine echte Erweiterungsmethode. Dies funktioniert nur, weil Enum <> ein anderer Typ als System.Enum ist.
Kann die Klasse staticsicherstellen, dass sich alle Methoden wie Erweiterungen verhalten?
Jatin Sanghvi
15
Für zukünftige Leser: Die Namensmehrdeutigkeit von Enum<T>ist etwas verwirrend. Die Klasse könnte auch aufgerufen werden EnumUtils<T>und der Methodenaufruf würde in aufgelöst EnumUtils<Duration>.Count.
Namoshek
46
Natürlich können Sie zum Beispiel das DescriptionAttribuefür Ihre enumWerte verwenden:
using System.ComponentModel.DataAnnotations;publicenumDuration{[Description("Eight hours")]Day,[Description("Five days")]Week,[Description("Twenty-one days")]Month}
Jetzt möchten Sie in der Lage sein, etwas zu tun wie:
Duration duration =Duration.Week;var description = duration.GetDescription();// will return "Five days"
Ihre Erweiterungsmethode GetDescription()kann wie folgt geschrieben werden:
using System.ComponentModel;
using System.Reflection;publicstaticstringGetDescription(thisEnumvalue){FieldInfo fieldInfo =value.GetType().GetField(value.ToString());if(fieldInfo ==null)returnnull;var attribute =(DescriptionAttribute)fieldInfo.GetCustomAttribute(typeof(DescriptionAttribute));return attribute.Description;}
Ich wollte eine Erweiterung für fast genau das erstellen, was Sie als Beispiel getan haben, mit Ausnahme meiner Verwendung von DisplayAttribute Localized GetDescription. Prost
George
Dies ist eine schöne Alternative, obwohl ich denke, dass der Namespace nur System.ComponentModel ist?
TomDestry
Schöne Perspektive und danke, dass Sie die Implementierung sowie den Erweiterungscode gezeigt haben. Zum Anhäufen: Mit Ihrer Implementierung können Sie es auch folgendermaßen aufrufen: var description = Duration.Week.GetDescription ();
Spencer Sullivan
30
Alle Antworten sind großartig, aber es geht darum, einer bestimmten Art von Aufzählung eine Erweiterungsmethode hinzuzufügen.
Was ist, wenn Sie allen Aufzählungen eine Methode hinzufügen möchten, z. B. die Rückgabe eines int mit dem aktuellen Wert anstelle einer expliziten Umwandlung?
publicstaticclassEnumExtensions{publicstaticintToInt<T>(this T soure)where T :IConvertible//enum{if(!typeof(T).IsEnum)thrownewArgumentException("T must be an enumerated type");return(int)(IConvertible) soure;}//ShawnFeatherly funtion (above answer) but as extention methodpublicstaticintCount<T>(this T soure)where T :IConvertible//enum{if(!typeof(T).IsEnum)thrownewArgumentException("T must be an enumerated type");returnEnum.GetNames(typeof(T)).Length;}}
Der Trick dahinter IConvertibleist die Vererbungshierarchie, siehe MDSN
Das Gleiche gilt. Es funktioniert, wenn ich die Nebenstelle direkt MyExtention.DoThing(myvalue)myvalue.DoThing()
anrufe
1
Zu
Ihrer Information
7
Sie können auch für alles eine Erweiterung erstellen object(obwohl dies nicht als Best Practice angesehen wird ). Verstehen Sie eine Erweiterungsmethode nur als public staticMethode. Sie können für Methoden einen beliebigen Parametertyp verwenden.
Ein voidRückgabewert für eine Aufzählung ist irgendwie komisch. Ich würde über eine realistischere Stichprobe nachdenken.
Psubsee2003
3
@ psubsee2003 hat das OP sicherlich genug Wissen, um dies an seine Bedürfnisse anzupassen? Warum ist das Beispiel wichtig? Es reicht aus, um die erste Frage zu beantworten.
LukeHennerley
3
Bin ich der einzige, der die Codebeispiele auf MSDN komisch findet? Meistens müssen Sie sich wirklich anstrengen, um zu verstehen, was sie versuchen!
TimeSpan
Day.IsWorkday()
über(Day & Days.Workday) > 0
mitDays.Workday
definiertMonday | Tuesday ... | Friday
. Ersteres ist meiner Meinung nach klarer und hat genau Letzteres umgesetzt.Antworten:
Laut dieser Seite :
Erweiterungsmethoden bieten eine Möglichkeit, Methoden für vorhandene Klassen so zu schreiben, wie andere Personen in Ihrem Team sie möglicherweise tatsächlich entdecken und verwenden. Angesichts der Tatsache, dass Aufzählungen Klassen wie jede andere sind, sollte es nicht allzu überraschend sein, dass Sie sie erweitern können, wie zum Beispiel:
Ich denke, Aufzählungen sind im Allgemeinen nicht die beste Wahl, aber zumindest können Sie so einen Teil des Schalters / der Handhabung zentralisieren und ein wenig abstrahieren, bis Sie etwas Besseres tun können. Denken Sie daran, zu überprüfen, ob die Werte ebenfalls im Bereich liegen.
Weitere Informationen finden Sie hier bei Microsft MSDN.
quelle
Duration d = 0;
Given that enums are classes
Nein, sie sind keine Klassen.Sie können dem Aufzählungstyp auch eine Erweiterungsmethode anstelle einer Instanz der Aufzählung hinzufügen:
Sie können die oben beschriebene Erweiterungsmethode aufrufen, indem Sie Folgendes tun:
Es ist keine echte Erweiterungsmethode. Dies funktioniert nur, weil Enum <> ein anderer Typ als System.Enum ist.
quelle
static
sicherstellen, dass sich alle Methoden wie Erweiterungen verhalten?Enum<T>
ist etwas verwirrend. Die Klasse könnte auch aufgerufen werdenEnumUtils<T>
und der Methodenaufruf würde in aufgelöstEnumUtils<Duration>.Count
.Natürlich können Sie zum Beispiel das
DescriptionAttribue
für Ihreenum
Werte verwenden:Jetzt möchten Sie in der Lage sein, etwas zu tun wie:
Ihre Erweiterungsmethode
GetDescription()
kann wie folgt geschrieben werden:quelle
Alle Antworten sind großartig, aber es geht darum, einer bestimmten Art von Aufzählung eine Erweiterungsmethode hinzuzufügen.
Was ist, wenn Sie allen Aufzählungen eine Methode hinzufügen möchten, z. B. die Rückgabe eines int mit dem aktuellen Wert anstelle einer expliziten Umwandlung?
Der Trick dahinter
IConvertible
ist die Vererbungshierarchie, siehe MDSNVielen Dank an ShawnFeatherly für seine Antwort
quelle
MyExtention.DoThing(myvalue)
myvalue.DoThing()
Sie können auch für alles eine Erweiterung erstellen
object
(obwohl dies nicht als Best Practice angesehen wird ). Verstehen Sie eine Erweiterungsmethode nur alspublic static
Methode. Sie können für Methoden einen beliebigen Parametertyp verwenden.quelle
Siehe MSDN .
quelle
void
Rückgabewert für eine Aufzählung ist irgendwie komisch. Ich würde über eine realistischere Stichprobe nachdenken.Wir haben gerade eine Enum-Erweiterung für c # https://github.com/simonmau/enum_ext erstellt
Es ist nur eine Implementierung für das Typensafeenum, aber es funktioniert großartig, also haben wir ein Paket zum Teilen erstellt - viel Spaß damit
Ich weiß, dass das Beispiel irgendwie nutzlos ist, aber Sie bekommen die Idee;)
quelle
Eine einfache Problemumgehung.
quelle