自动属性的默认接口方法和默认值

Default interface methods and default values for Auto Properties

鉴于自动 属性 编译为 get_method、set_method 和私有变量,并且由于 C# 8 正在引入默认接口方法

接口中的属性可以有默认实现吗?

特别是只获得属性?

没有


提案说:

Interfaces may not contain instance state. While static fields are now permitted, instance fields are not permitted in interfaces. Instance auto-properties are not supported in interfaces, as they would implicitly declare a hidden field.

(source)

另请参阅第 9 频道采访A Preview of C# 8 with Mads Torgersen,他们在其中谈论默认接口实现等。


默认接口方法未包含在与 Visual Studio 2019 预览版 1 一起发布的 C# 8.0(测试版)中。在撰写本文时,默认接口方法原型仍在开发中.参考Champion "default interface methods".

是的。

自动属性不是 属性 的特殊类型。它们是一种方便的功能,可以生成在支持字段中存储 属性 值所需的代码。

您可以为 getter 和 setter 指定属性的默认实现。您可以在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;}
}

版本控制

这演示了版本控制方案。 Box 实施了一个仅包含 HeightWidthIDimensions 版本。

Weight 后来添加了默认实现 returns 0 并忽略写入。 Density 添加了一个默认实现,即 return 是盒子的 volume/density,如果没有有效权重则为 0。 Box 即使淡入淡出也不必更改。即使编译器生成的代码也没有显示对 Box class.

的任何更改

类 可以用自己的替换默认实现。没有什么能阻止 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();
}

此特征将 return 进行简单的密度计算并强制应用它的类型实现 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.iolinkis here