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 :
Erweiterungseigenschaften: Wir hatten einen (brillanten!) Praktikanten, der sie im Sommer als Experiment zusammen mit anderen Arten von Erweiterungsmitgliedern implementierte. Wir bleiben daran interessiert, aber es ist eine große Veränderung und wir müssen zuversichtlich sein, dass es sich lohnt.
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:
public interface IEmployee
{
public decimal Salary { get; set; }
}
public class Employee
{
public decimal Salary { get; set; }
}
public extension MyPersonExtension extends Person : IEmployee
{
private static readonly ConditionalWeakTable<Person, Employee> _employees =
new ConditionalWeakTable<Person, Employee>();
public decimal Salary
{
get
{
// `this` is the instance of Person
return _employees.GetOrCreate(this).Salary;
}
set
{
Employee employee = null;
if (!_employees.TryGetValue(this, out employee)
{
employee = _employees.GetOrCreate(this);
}
employee.Salary = value;
}
}
}
IEmployee person = new Person();
var salary = person.Salary;
Ä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, durch for
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:
Mithilfe von Rollen können Schnittstellen für bestimmte Werte eines bestimmten Typs implementiert werden. Mit Erweiterungen können Schnittstellen für alle Werte eines bestimmten Typs innerhalb eines bestimmten Codebereichs implementiert werden.
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:
public extension ULongEnumerable of ulong
{
public IEnumerator<byte> GetEnumerator()
{
for (int i = sizeof(ulong); i > 0; i--)
{
yield return unchecked((byte)(this >> (i-1)*8));
}
}
}
dann könnten Sie dies tun:
foreach (byte b in 0x_3A_9E_F1_C5_DA_F7_30_16ul)
{
WriteLine($"{e.Current:X}");
}
Und für eine statische Schnittstelle :
public interface IMonoid<T> where T : IMonoid<T>
{
static T operator +(T t1, T t2);
static T Zero { get; }
}
Fügen Sie eine Erweiterungseigenschaft auf int
und behandelt die int
als IMonoid<int>
:
public extension IntMonoid of int : IMonoid<int>
{
public static int Zero => 0;
}