Методы интерфейса по умолчанию и значения по умолчанию для 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 "методы интерфейса по умолчанию".

Другие вопросы по тегам