Методы интерфейса по умолчанию и значения по умолчанию для Auto Properties
Учитывая, что свойство auto компилируется в get_method, set_method и приватную переменную, а в C# 8 вводятся методы интерфейса по умолчанию
Могут ли свойства в интерфейсах иметь реализации по умолчанию?
Особенно получить только собственность?
2 ответа
Да.
Авто свойства не особый тип собственности. Это удобная функция, которая генерирует код, необходимый для хранения значений свойств в вспомогательном поле.
Вы можете указать реализацию по умолчанию для свойств, как для получения, так и для установки. Вы можете попробовать следующий код в https://sharplab.io/
public interface IDimensions
{
int Height {get;set;}
int Width {get;set;}
int Depth {get;set;}
int Weight { get=>0; set{} }
int Density { get=> Weight==0?0:Height*Width*Depth/Weight ; }
}
public class Box:IDimensions
{
public int Height{get;set;}
public int Width{get;set;}
}
Versioning
Это демонстрирует сценарий управления версиями. Box
реализовал версию IDimensions
это только включено Height
, Width
,
Weight
позже был добавлен с реализацией по умолчанию, которая возвращает 0 и игнорирует записи. Density
была добавлена реализация по умолчанию, которая возвращает объем / плотность блока, или 0, если нет действительного веса. Box
не нужно было менять, хотя интерфейс изменился. Даже код, сгенерированный компилятором, не показывает никаких изменений в Box
учебный класс.
Классы могут заменить реализации по умолчанию своими собственными. Ничто не мешает Box
от добавления int Weight {get;set;}
в будущем.
Реализации по умолчанию доступны только через интерфейс:
IDimensions box=new Box();
Console.WriteLine(box.Density);
Черты
Другой сценарий, который обрабатывается реализациями по умолчанию, это черты.
Давайте предположим, что я хочу добавить IDensity
черта к любому типу предмета. В большинстве случаев мне понадобится только объем и вес предмета для расчета его плотности:
public interface IDensity
{
int Density
{
get
{
var weight=getWeight();
if (weight==0) return 0;
return getVolume()/weight;
}
}
abstract int getWeight();
abstract int getVolume();
}
Эта черта вернет упрощенный расчет плотности и вынудит тип, к которому она применяется, реализовать int getWeight()
и int getHeight()
методы:
public class Crate:IDensity
{
//Dummy numbers
public int getWeight()=>55;
public int getVolume()=>100;
}
public class C {
public void M() {
IDensity box=new Cake();
Console.WriteLine(box.Density);
}
}
Другой контейнер может переопределить эту реализацию своей собственной. Возможно, контейнер имеет сложную форму:
public class WeddingCake:IDensity
{
public int getWeight()=>5;
public int getVolume()=>getWeight()/Density;
public int Density=>2;
}
Ссылка Sharplab.io для этого примера находится здесь
Нет.
Предложение говорит:
Интерфейсы могут не содержать состояние экземпляра. В то время как статические поля теперь разрешены, поля экземпляров не разрешены в интерфейсах. Авто-свойства экземпляра не поддерживаются в интерфейсах, поскольку они неявно объявляют скрытое поле.
( источник)
Смотрите также интервью на канале 9 "Предварительный просмотр C# 8" с Мэдсом Торгерсеном, где они обсуждают, в частности, реализации интерфейса по умолчанию.
Методы интерфейса по умолчанию не включены в C# 8.0 (бета), который был выпущен в Visual Studio 2019 Preview 1. На момент написания прототип методов интерфейса по умолчанию все еще находился в разработке. Обратитесь к Champion "методы интерфейса по умолчанию".