W tej chwili kompilator Roslyn nie obsługuje go już po wyjęciu z pudełka ...
Do tej pory właściwości rozszerzenia nie były postrzegane jako wystarczająco wartościowe, aby można je było uwzględnić w poprzednich wersjach standardu C #. C # 7 i C # 8.0 postrzegają to jako mistrza propozycji, ale nie zostało jeszcze wydane, przede wszystkim dlatego, że nawet jeśli istnieje już implementacja, chcą to zrobić od samego początku.
Ale to będzie ...
Na liście prac w C # 7 znajduje się element rozszerzenia, więc może być obsługiwany w najbliższej przyszłości. Bieżący status właściwości rozszerzenia można znaleźć na Github w powiązanej pozycji .
Istnieje jednak jeszcze bardziej obiecujący temat, którym jest „rozszerzenie wszystkiego” ze szczególnym uwzględnieniem właściwości i klas statycznych, a nawet pól.
Ponadto możesz użyć obejścia
Jak określono w tym artykule , można użyć TypeDescriptor
możliwości dołączenia atrybutu do instancji obiektu w czasie wykonywania. Jednak nie używa składni standardowych właściwości.
Różni się nieco od cukru syntaktycznego, dodając możliwość zdefiniowania rozszerzonej właściwości, takiej
string Data(this MyClass instance)
jak alias metody rozszerzenia,
string GetData(this MyClass instance)
ponieważ przechowuje dane w klasie.
Mam nadzieję, że C # 7 zapewni w pełni funkcjonalne rozszerzenie wszystkiego (właściwości i pola), jednak w tym momencie tylko czas pokaże.
I nie krępuj się przyłączyć, ponieważ oprogramowanie jutra będzie pochodziło od społeczności.
Aktualizacja: sierpień 2016 r
Gdy zespół dotnet opublikował nowości w C # 7.0 oraz komentarz Madsa Torgensena :
Właściwości rozszerzenia: mieliśmy (genialnego!) Stażystę, który wdrożył je latem jako eksperyment, wraz z innymi rodzajami członków rozszerzenia. Nadal jesteśmy tym zainteresowani, ale to duża zmiana i musimy mieć pewność, że warto.
Wygląda na to, że właściwości rozszerzenia i inni członkowie nadal są dobrymi kandydatami do włączenia w przyszłej wersji Roslyn, ale może nie w wersji 7.0.
Aktualizacja: maj 2017 r
Elementy rozszerzenia zostały zamknięte jako duplikat rozszerzenia wszystko, co również zostało zamknięte. Główna dyskusja dotyczyła w gruncie rzeczy rozszerzalności typu. Funkcja jest teraz śledzona tutaj jako propozycja i została usunięta z kamienia milowego 7.0 .
Aktualizacja: sierpień 2017 - proponowana funkcja C # 8.0
Chociaż nadal pozostaje tylko proponowaną funkcją, mamy teraz wyraźniejszy pogląd na jego składnię. Pamiętaj, że będzie to również nowa składnia metod rozszerzeń:
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;
Podobne do klas częściowych, ale skompilowane jako osobna klasa / typ w innym zestawie. Uwaga: w ten sposób będziesz mógł dodawać statyczne elementy i operatory. Jak wspomniano w podcastie Madsa Torgensena , rozszerzenie nie będzie miało żadnego stanu (więc nie może dodawać prywatnych członków instancji do klasy), co oznacza, że nie będzie można dodawać danych prywatnych instancji powiązanych z instancją . Powodem jest to, że sugerowałoby to zarządzanie wewnętrznymi słownikami i może być trudne (zarządzanie pamięcią itp.). W tym celu możesz nadal korzystać z opisanej wcześniej techniki TypeDescriptor
/ ConditionalWeakTable
iz rozszerzeniem właściwości ukrywa ją pod ładną właściwością.
Składnia nadal może ulec zmianie, ponieważ implikuje ten problem . Na przykład extends
można je zastąpić for
niektórymi, którzy mogą czuć się bardziej naturalni i mniej związani z javą.
Aktualizacja grudzień 2018 r. - Role, rozszerzenia i statyczne elementy interfejsu
Rozszerzenie wszystko nie udało się do C # 8.0, z powodu niektórych wad wyjaśnionych jako koniec tego biletu GitHub . Przeprowadzono więc eksplorację w celu ulepszenia projektu. Tutaj Mads Torgensen wyjaśnia, jakie są role i rozszerzenia oraz czym się różnią:
Role umożliwiają implementację interfejsów na określonych wartościach danego typu. Rozszerzenia pozwalają na implementację interfejsów dla wszystkich wartości danego typu w obrębie określonego regionu kodu.
Można to zaobserwować na podzieleniu poprzedniej propozycji w dwóch przypadkach użycia. Nowa składnia przedłużenie byłoby tak:
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));
}
}
}
wtedy będziesz w stanie to zrobić:
foreach (byte b in 0x_3A_9E_F1_C5_DA_F7_30_16ul)
{
WriteLine($"{e.Current:X}");
}
A dla interfejsu statycznego :
public interface IMonoid<T> where T : IMonoid<T>
{
static T operator +(T t1, T t2);
static T Zero { get; }
}
Dodawanie właściwości Extension na int
i traktować int
jako IMonoid<int>
:
public extension IntMonoid of int : IMonoid<int>
{
public static int Zero => 0;
}