Hat C # Erweiterungseigenschaften?
Zum Beispiel kann ich eine Erweiterung Eigenschaft hinzufügen DateTimeFormatInfo
genannt , ShortDateLongTimeFormat
die zurückkommen würde ShortDatePattern + " " + LongTimePattern
?
c#
properties
extension-methods
Svish
quelle
quelle
?
enum
nachahmt, die Eigenschaften und Methoden haben können. C #enum
können keine Eigenschaften oder Methoden haben, aber Sie können Erweiterungsmethoden für sie erstellen. Diese Frage war nützlich für mich und sollte nicht geschlossen werden.Antworten:
Im Moment wird es vom Roslyn-Compiler noch nicht sofort unterstützt ...
Bisher wurden die Erweiterungseigenschaften nicht als wertvoll genug angesehen, um in früheren Versionen des C # -Standards enthalten zu sein. C # 7 und C # 8.0 haben dies als Vorschlagschampion gesehen, aber es wurde noch nicht veröffentlicht, vor allem, weil sie es von Anfang an schaffen wollen, auch wenn es bereits eine Implementierung gibt.
Aber es wird ...
Es gibt ein Verlängerungselement Element in der C # 7 Arbeitsliste , so dass es in naher Zukunft unterstützt werden. Der aktuelle Status der Erweiterungseigenschaft finden Sie auf Github unter dem zugehörigen Element .
Es gibt jedoch ein noch vielversprechenderes Thema, nämlich "Alles erweitern", wobei der Schwerpunkt auf Eigenschaften und statischen Klassen oder sogar Feldern liegt.
Darüber hinaus können Sie eine Problemumgehung verwenden
Wie in diesem Artikel angegeben , können Sie die
TypeDescriptor
Funktion verwenden, um zur Laufzeit ein Attribut an eine Objektinstanz anzuhängen. Es wird jedoch nicht die Syntax der Standardeigenschaften verwendet.Es unterscheidet sich ein wenig von syntaktischem Zucker und bietet die Möglichkeit, eine erweiterte Eigenschaft wie
string Data(this MyClass instance)
einen Alias für die Erweiterungsmethode zu definieren ,string GetData(this MyClass instance)
wenn Daten in der Klasse gespeichert werden.Ich hoffe, dass C # 7 alles (Eigenschaften und Felder) mit allen Funktionen bietet, aber in diesem Punkt wird es nur die Zeit zeigen.
Und zögern Sie nicht, einen Beitrag zu leisten, da die Software von morgen von der Community kommt.
Update: August 2016
Als Dotnet-Team veröffentlichte, was in C # 7.0 neu ist und aus einem Kommentar von Mads Torgensen :
Es scheint, dass Erweiterungseigenschaften und andere Mitglieder immer noch gute Kandidaten für eine zukünftige Version von Roslyn sind, aber möglicherweise nicht die Version 7.0.
Update: Mai 2017
Die Erweiterungsmitglieder wurden als Duplikat der Erweiterung geschlossen. Alles, was ebenfalls geschlossen ist. Die Hauptdiskussion befasste sich in der Tat mit der Erweiterbarkeit von Typen im weiteren Sinne. Die Funktion wird jetzt hier als Vorschlag verfolgt und aus dem 7.0-Meilenstein entfernt .
Update: August 2017 - Vorgeschlagene Funktion für C # 8.0
Während es immer noch nur ein vorgeschlagenes Feature bleibt , haben wir jetzt eine klarere Sicht auf die Syntax. Beachten Sie, dass dies auch die neue Syntax für Erweiterungsmethoden sein wird:
Ähnlich wie Teilklassen, jedoch als separate Klasse / Typ in einer anderen Assembly kompiliert. Beachten Sie, dass Sie auf diese Weise auch statische Elemente und Operatoren hinzufügen können. Wie im Podcast von Mads Torgensen erwähnt , hat die Erweiterung keinen Status (daher können der Klasse keine privaten Instanzmitglieder hinzugefügt werden), was bedeutet, dass Sie keine mit der Instanz verknüpften privaten Instanzdaten hinzufügen können . Der Grund dafür ist, dass interne Wörterbücher verwaltet werden müssen und dies schwierig sein kann (Speicherverwaltung usw.). Dazu können Sie weiterhin die zuvor beschriebene
TypeDescriptor
/ConditionalWeakTable
-Technik verwenden und sie mit der Eigenschaftserweiterung unter einer schönen Eigenschaft ausblenden.Die Syntax kann sich weiterhin ändern, da dies dieses Problem impliziert . Zum Beispiel
extends
könnte ersetzt werden, durchfor
die sich einige natürlicher und weniger mit Java verbunden fühlen.Update Dezember 2018 - Rollen, Erweiterungen und statische Schnittstellenmitglieder
Die Erweiterung hat es nicht auf C # 8.0 geschafft, da einige Nachteile als Ende dieses GitHub-Tickets erklärt wurden . Es gab also eine Untersuchung, um das Design zu verbessern. Hier erklärt Mads Torgensen, was Rollen und Erweiterungen sind und wie sie sich unterscheiden:
Es kann bei einer Aufteilung des vorherigen Vorschlags in zwei Anwendungsfälle gesehen werden. Die neue Syntax für die Erweiterung würde folgendermaßen aussehen:
dann könnten Sie dies tun:
Und für eine statische Schnittstelle :
Fügen Sie eine Erweiterungseigenschaft auf
int
und behandelt dieint
alsIMonoid<int>
:quelle
Nein, sie sind in C # 3.0 nicht vorhanden und werden in 4.0 nicht hinzugefügt. Es befindet sich auf der Liste der gewünschten Funktionen für C #, sodass es zu einem späteren Zeitpunkt hinzugefügt werden kann.
Zu diesem Zeitpunkt können Sie am besten Erweiterungsmethoden im GetXXX-Stil verwenden.
quelle
Nein, sie existieren nicht.
Ich weiß, dass das C # -Team sie zu einem bestimmten Zeitpunkt in Betracht gezogen hat (oder zumindest Eric Lippert) - zusammen mit Erweiterungskonstruktoren und -betreibern (es kann eine Weile dauern, bis Sie sich zurechtfinden, aber sie sind cool ...) Ich habe keine Beweise dafür gesehen, dass sie Teil von C # 4 sein werden.
EDIT: Sie sind nicht in C # 5 erschienen und ab Juli 2014 sieht es auch nicht so aus, als würde es in C # 6 sein.
Eric Lippert , der Hauptentwickler im C # -Compilerteam von Microsoft bis November 2012, hat im Oktober 2009 darüber gebloggt:
quelle
()
am Ende loszuwerden ist viel besser lesbar. Ich weiß für mich persönlich, dass mindestens 90% der Erweiterungen, die ich schreibe, von diesen beiden Typen sind.FullName
=FirstName + LastName
,ShortName
=FirstName + LastName[0]
. Ich möchte weitere dieser Eigenschaften hinzufügen, möchte aber die tatsächlichen Klassen nicht "verschmutzen". In diesem Fall ist eine schreibgeschützte Erweiterungseigenschaft perfekt, da ich die Funktionalität hinzufügen, die Hauptklasse sauber halten und dennoch die Informationen verfügbar machen kann, die ich in der Benutzeroberfläche verfügbar machen möchte.static implicit operator FileInfo(FileInfoEx fex)
welches mein enthaltenes FileInfo-Objekt zurückgibt. Auf diese Weise kann ich FileInfoEx effektiv so behandeln, als würde es von FileInfo erben, obwohl diese Klasse versiegelt ist.Update (danke an @chaost für den Hinweis auf dieses Update):
Quelle: Kommentarbereich in https://blogs.msdn.microsoft.com/dotnet/2018/11/12/building-c-8-0/
Ich habe aufgehört zu zählen, wie oft ich diese Frage im Laufe der Jahre geöffnet habe, in der Hoffnung, dass dies umgesetzt wurde.
Nun, endlich können wir uns alle freuen! Microsoft wird dies in der kommenden C # 8-Version vorstellen.
Also anstatt dies zu tun ...
Wir werden es endlich so machen können ...
Quelle: https://blog.ndepend.com/c-8-0-features-glimpse-future/
quelle
Wie bei @Psyonity erwähnt, können Sie mit der conditionalWeakTable vorhandenen Objekten Eigenschaften hinzufügen. In Kombination mit dem dynamischen ExpandoObject können Sie dynamische Erweiterungseigenschaften in wenigen Zeilen implementieren:
Ein Verwendungsbeispiel finden Sie in den XML-Kommentaren:
quelle
Da ich dies kürzlich brauchte, habe ich mir die Quelle der Antwort in folgenden Abschnitten angesehen:
c # Klasse durch Hinzufügen von Eigenschaften erweitern
und eine dynamischere Version erstellt:
Es kann wahrscheinlich stark verbessert werden (Benennung, dynamisch anstelle von Zeichenfolge). Ich verwende dies derzeit in CF 3.5 zusammen mit einer hackigen ConditionalWeakTable ( https://gist.github.com/Jan-WillemdeBruyn/db79dd6fdef7b9845e217958db98c4d4 ).
quelle