На данный момент это все еще не поддерживается из коробки компилятором 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 и из комментария Мадса Торгенсена :
Свойства расширения: у нас был (блестящий!) Стажер, который реализовывал их летом в качестве эксперимента, вместе с другими видами членов расширения. Мы по-прежнему заинтересованы в этом, но это большое изменение, и мы должны быть уверены, что оно того стоит.
Кажется, что свойства расширения и другие члены все еще являются хорошими кандидатами для включения в будущий выпуск 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;
}