На данный момент он все еще не поддерживается из коробки компилятором Roslyn ...
До сих пор свойства расширения не рассматривались как достаточно ценные для включения в предыдущие версии стандарта C #. C # 7 и C # 8.0 считают это чемпионом предложения, но оно еще не было выпущено, прежде всего потому, что даже если уже есть реализация, они хотят сделать это правильно из начало.
Но это будет ...
В рабочем списке C # 7 есть элемент расширения расширения , поэтому он может быть поддержан в ближайшем будущем. Текущий статус свойства extension можно найти на Github под соответствующим элементом .
Однако есть еще более многообещающая тема: "Расширить все" с акцентом на особенности свойств и статических классов или даже полей.
Кроме того, вы можете использовать обходной путь
Как указано в этой статье , вы можете использовать возможность TypeDescriptor
для присоединения атрибута к экземпляру объекта во время выполнения. Однако он не использует синтаксис стандартных свойств.
Это немного отличается от простого синтаксического сахара, добавляющего возможность определять расширенное свойство, такое как
string Data(this MyClass instance)
, в качестве псевдонима для метода расширения
string GetData(this MyClass instance)
, поскольку оно хранит данные в классе.
Я надеюсь, что C # 7 предоставит полнофункциональное расширение для всего (свойства и поля), однако на данный момент только время покажет.
И не стесняйтесь вносить свой вклад, поскольку программное обеспечение завтрашнего дня придет от сообщества.
Обновление: август 2016
Как команда dotnet опубликовала что нового в 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 podcast , расширение не будет иметь никакого состояния (поэтому оно не может добавлять частные элементы экземпляра в класс), что означает, что вы не сможете добавлять частные Данные экземпляра связаны с экземпляром . Причина, по которой это вызвано, заключается в том, что это подразумевает управление внутренними словарями, и это может быть сложно (управление памятью и т. Д.).
Для этого вы все еще можете использовать метод 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;
}