Наразі компілятор Roslyn він все ще не підтримується з коробки ...
До цих пір властивості розширення не розглядалися як такі цінні, щоб їх можна було включити в попередні версії стандарту C #. C # 7 і C # 8.0 вважали це чемпіоном пропозицій, але його ще не було випущено, тим більше, що навіть якщо вже є реалізація, вони хочуть зробити це з самого початку.
Але це буде ...
У робочому списку C # 7 є пункт членів розширення, тому він може бути підтриманий найближчим часом. Поточний статус властивості розширення можна знайти в Github під відповідним пунктом .
Однак є ще більш перспективна тема - це "розширити все" з акцентом на особливо властивості та статичні класи чи навіть поля.
Крім того, ви можете використовувати вирішення
Як зазначено в цій статті , ви можете використовувати TypeDescriptor
можливість приєднання атрибута до екземпляра об'єкта під час виконання. Однак він не використовує синтаксис стандартних властивостей.
Це трохи відрізняється від просто синтаксичного цукру, додаючи можливість визначити розширене властивість, наприклад
string Data(this MyClass instance)
, псевдонім для методу розширення,
string GetData(this MyClass instance)
оскільки він зберігає дані в клас.
Я сподіваюся, що C # 7 надасть повне розширене розширення для всіх (властивостей та полів), проте з цього приводу покаже лише час.
І не соромтесь робити внесок, оскільки програмне забезпечення завтра буде надходити від громади.
Оновлення: серпень 2016 року
Як дотнет команда опублікувала, що нового в C # 7.0 та з коментаря Mads Torgensen :
Властивості розширення: у нас (геніальний!) Стажер впроваджував їх протягом літа як експеримент разом з іншими видами членів розширення. Ми все ще зацікавлені в цьому, але це велика зміна, і нам потрібно впевнено почувати, що воно того варте.
Здається, що властивості розширення та інші члени, як і раніше, є хорошими кандидатами для включення у майбутній випуск Roslyn, але, можливо, не 7.0.
Оновлення: травень 2017 року
Члени розширення закриті як дублікат розширення, і все питання, яке закрито. Основна дискусія була насправді про розширюваність типу в широкому розумінні. Тепер ця функція відстежується тут як пропозиція, і вона була вилучена із 7.0 етапу .
Оновлення: серпень 2017 р. - запропонована функція C # 8.0
Хоча це все ще залишається лише запропонованою функцією, ми маємо чіткіше уявлення про те, яким би був його синтаксис. Майте на увазі, що це буде новий синтаксис і для методів розширення:
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;
Схожий на часткові класи, але складений як окремий клас / тип в іншій збірці. Зауважте, ви також зможете додавати статичні члени та оператори таким чином. Як згадується в подкасті Mads Torgensen , розширення не матиме жодного стану (тому він не може додавати приватних членів екземпляра до класу), що означає, що ви не зможете додавати приватні дані, пов'язані з екземпляром . Причина, на яку посилається, полягає в тому, що це означатиме, що керувати внутрішніми словниками, і це може бути складно (управління пам'яттю тощо). Для цього ви все ще можете використовувати TypeDescriptor
/ ConditionalWeakTable
описану раніше техніку та з розширенням властивості, ховає її під приємним властивістю.
Синтаксис все ще може бути змінений, як випливає з цього питання . Наприклад, extends
може бути замінено тим, for
що деякі можуть відчувати себе більш природними та менш java пов'язаними.
Оновлення грудня 2018 року - ролі, розширення та статичні учасники інтерфейсу
Розширення все не призвело до C # 8.0, через деякі недоліки, пояснені як кінець цього квитка на GitHub . Отже, була проведена розвідка для вдосконалення дизайну. Тут Мадс Торгенсен пояснює, що таке ролі та розширення та чим вони відрізняються:
Ролі дозволяють реалізувати інтерфейси за певними значеннями заданого типу. Розширення дозволяють реалізувати інтерфейси для всіх значень заданого типу в межах конкретної області коду.
Це можна побачити при розщепленні попередньої пропозиції у двох випадках використання. Новий синтаксис для розширення буде виглядати так:
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));
}
}
}
тоді ви зможете це зробити:
foreach (byte b in 0x_3A_9E_F1_C5_DA_F7_30_16ul)
{
WriteLine($"{e.Current:X}");
}
А для статичного інтерфейсу :
public interface IMonoid<T> where T : IMonoid<T>
{
static T operator +(T t1, T t2);
static T Zero { get; }
}
Додати властивість розширення на int
і лікувати , int
як IMonoid<int>
:
public extension IntMonoid of int : IMonoid<int>
{
public static int Zero => 0;
}