当你升级到 C# 8.0 和 .NET Core 3.0 之后,你就可以开始使用默认接口实现的功能了。

从现在开始,你可以在接口里面添加一些默认实现的成员,避免在接口中添加成员导致大量对此接口的实现崩溃。

要写出并且正常使用接口的默认实现,你需要:

  • C# 8.0

  • .NET Core 3.0

  • Visual Studio 2019 Preview (16.1 以上版本)

  • 前往下载安装 Visual Studio Preview

对于预览版的 Visual Studio 2019 来说,.NET Core 的预览版是默认打开且无法关闭的,所以不需要关心。

请设置你项目的属性,修改 C# 语言版本为 8.0(对于预览版的语言来说,这是必要的):

或者直接修改你的项目文件,加上 LangVersion 属性的设置,设置为 8.0。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>    <OutputType>Exe</OutputType>    <TargetFramework>netcoreapp3.0</TargetFramework>    <LangVersion>8.0</LangVersion>  </PropertyGroup>

</Project>

比如,我们现在有下面这样一个简单的接口:

public interface IWalterlv{    void Print(string text);}

这个接口被大量实现了。

现在,我们需要在接口中新增一个方法 DouBPrint,其作用是对 Print 方法进行标准化,避免各种不同实现带来的标准差异。于是我们新增一个方法:

    public interface IWalterlv    {        void Print(string text);

++      void DouBPrint(string text);    }

然而我们都知道,这样的修改是破坏性的:

  1. 会使得所有实现这个接口的代码全部失败(无法编译通过,或者运行时抛出异常)

  2. 我们依然很难将接口的实现标准化,靠文档来规约

那么现在,我们可以这样来新增此方法:

    public interface IWalterlv    {        void Print(string text);

--      void DouBPrint(string text);++      public void DouBPrint(string text) => Print($"Walterlv 逗比 {text}");    }

在使用此方法来定义此接口中的方法后,那些没来得及实现此方法的类型也可以编译通过并获得标准化的实现。

class Program{    static void Main(string[] args)    {        IWalterlv walterlv = new Foo();        walterlv.DouBPrint("walterlv");    }}

public class Foo : IWalterlv{    public void Print(string text)    {    }}

当然,对于 Foo 类型来说,实现也是可以的:

public class Foo : IWalterlv{    public void Print(string text)    {    }

    public void DouBPrint(string text) => Print($"Walterlv 逗比 {text}");}

除此之外,在接口中还可以编写静态字段和静态方法,这可以用来统一接口中的一些默认实现。

意味着,如果类没有实现接口中带有默认实现的方法,那么具有默认的实现;而如果类中打算实现接口中的带有默认实现的方法,那么也可以调用接口中的静态方法来进行实现。

    public interface IWalterlv    {        void Print(string text);

--      public void DouBPrint(string text) => Print($"Walterlv 逗比 {text}");++      public void DouBPrint(string text) => DefaultDouBPrint(this, text);++++      private static readonly string _name = "walterlv";++++      protected static void DefaultDouBPrint(IWalterlv walterlv, string text)++          => walterlv.Print($"{_name} 逗比 {text}");    }

然后,对于实现方,则需要使用接口名来调用接口中的静态成员:

    public class Foo : IWalterlv    {        public void Print(string text)        {        }

--      public void DouBPrint(string text) => Print($"Walterlv 逗比 {text}");++      public void DouBPrint(string text)++      {++          // Do Other things.++          IWalterlv.DefaultDouBPrint(this, text);++      }++  }

参考资料

  • Default implementations in interfaces - .NET Blog

  • Visual Studio 2019 version 16.1 Preview 3 - The Visual Studio Blog

  • Safely update interfaces using default interface members in C# - Microsoft Docs

原文地址:https://walterlv.com/post/default-interface-members-practise.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 

C# 8.0 中开启默认接口实现相关推荐

  1. 如何在 C# 8 中使用默认接口方法

    C# 8 中新增了一个非常有趣的特性,叫做 默认接口方法 (又称虚拟扩展方法),这篇文章将会讨论 C# 8 中的默认接口方法以及如何使用. 在 C# 8 之前,接口不能包含方法定义,只能在接口中定义方 ...

  2. [译]C#8.0中一个使接口更加灵活的新特性-默认接口实现

    9月份的时候,微软宣布正式发布C#8.0,作为.NET Core 3.0发行版的一部分.C#8.0的新特性之一就是默认接口实现.在本文中,我们将一起来聊聊默认接口实现. 众所周知,对现有应用程序的接口 ...

  3. C# 8中的默认接口方法

    \ 关键要点 \\ 默认接口方法已经被包含在C# 8的新功能建议中,开发人员可以像使用trait那样使用默认方法.\\t trait是面向对象的编程技术,用于提升不相关类之间方法的重用性.\\t C# ...

  4. Geronimo3.0中配置默认的security

    在Geronimo服务器中,基本的安全配置分成两个插件: j2ee-security和server-security-config.其中jaac provider和keystore manager在j ...

  5. ATS 5.3.0中开启最高级别的缓存调试信息

    近来在pptv,letv之类的站点响应中看到via头中有非常详细的缓存信息,我研究了一下,原来是ATS默认就支持的,以ATS 5.3.0中为例,修改records.config中的如下配置项: CON ...

  6. asp.net 2.0中设定默认焦点按钮

    在asp.net 1.1中,当要在page_load页面中,设置某个控件为默认的焦点按钮(也就是默认焦点是在这个控件上的),可能要用到javascript的代码,而在ASP.NET 2.0中,不用这些 ...

  7. 华为鸿蒙11公测版,EMUI 11首批公测升级机型 鸿蒙OS2.0已开启公共接口

    9月10日华为正式发布了EMUI 11,主打三大亮点"人因UX设计.创新全场景体验.科技守护隐私安全",当天便开启了Beta测试,根据华为官方宣称,EMUI 11将支持50款华为手 ...

  8. 在Tomcat7.0中设置默认服务器和不加端口名访问

    前言 昨天买了域名,服务器,然后搭建了环境,然后想他通过默认的端口,不用端口就访问. 设置WEB项目的欢迎页 在WEB-INF文件夹下有个web.xml文件(最近新建的项目不包含此文件,可以手动新建) ...

  9. android 4.0中修改默认输入法

    在 android4.0/frameworks/base/services/java/com/android/server/InputMethodManagerService.java中 void b ...

最新文章

  1. 编写程序,输出所有3位数的水仙花数
  2. php7.1安装redis,php7安装redis扩展
  3. Redis缓存高可用集群哨兵模式详解
  4. 机器学习之——学习率
  5. eclipse 快捷键组合
  6. 进阶4:hive 安装
  7. flask 接口 让别人能访问_flask搭建一个前后端分离的系统
  8. 字节新产品「识区APP」上线
  9. argparse、glob、findall
  10. 我们自身的认知可以改变吗?
  11. Socket编程Http下载的简单实现
  12. 记百人计划--测试思路
  13. SPLUS软件授权管理必知
  14. python爬虫——40行代码爬取「笔趣看」全部小说
  15. 华硕ac68u无线最佳设置_华硕AC86U,AC88U的掉线、断流问题何时彻底解决?
  16. 无法在浏览器中创建CAD文档
  17. 第4章 点云的滤波与分类 4.1点云数据的过滤
  18. APK文件使用ApkTool解包反编译和重新打包及签名
  19. 讲人话科普,Python是个啥?为啥大家都在学?
  20. 如何快速的了解gpt

热门文章

  1. 如何将Outgoing Webhook部署到中国版Azure
  2. 【Python】猜数小游戏(文件操作)
  3. 前端实现连连看小游戏(1)
  4. 0408~送给小伙伴的汉堡包
  5. (译)Windsor入门教程---第三部分 编写第一个Installer
  6. 深入理解jQuery中$.get、$.post、$.getJSON和$.ajax的用法
  7. 如何通过 HttpWebRequest 上传文件?
  8. 在ASP.Net Core和JAVA中,使用Azure配置密钥——Key Vault
  9. 号称迄今为止最快,.NET6带来了什么?
  10. Serverless 落地实践