默认界面方法和自动属性的默认值

时间:2018-12-10 07:04:15

标签: c# c#-8.0

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

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

特别是仅获取属性?

2 个答案:

答案 0 :(得分:2)

否。


该建议说:

  

接口可能不包含实例状态。虽然现在允许使用静态字段,但在接口中不允许使用实例字段。接口不支持实例自动属性,因为它们会隐式声明一个隐藏字段。

source

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


默认接口方法不随Visual Studio 2019 Preview 1一起发布的C#8.0(测试版)中包括。在编写本文时,默认接口方法原型仍在开发中。请参阅Champion "default interface methods"

答案 1 :(得分:1)

是的

自动属性不是一种特殊的属性。它们是一项便利功能,可生成将属性值存储在后备字段中所需的代码。

您可以为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实现了IDimensions的版本,其中仅包含HeightWidth

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;
}

此示例is here

的Sharplab.io链接