C# 8.0 中开启默认接口实现

当你升级到 C# 8.0 和 .NET Core 3.0 之后,你就可以开始使用默认接口实现的功能了。
从现在开始,你可以在接口里面添加一些默认实现的成员,避免在接口中添加成员导致大量对此接口的实现崩溃。
本文内容
最低要求
要写出并且正常使用接口的默认实现,你需要:
- C# 8.0
- .NET Core 3.0
- Visual Studio 2019 Preview (16.1 以上版本)
下载安装 Visual Studio 2019 Preview 版本
- 前往下载安装 Visual Studio Preview
开启 .NET Core 3.0 的支持
对于预览版的 Visual Studio 2019 来说,.NET Core 的预览版是默认打开且无法关闭的,所以不需要关心。
开启 C# 8.0 支持
请设置你项目的属性,修改 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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
默认接口实现
以前的做法
比如,我们现在有下面这样一个简单的接口:
public interface IWalterlv
{
void Print(string text);
}
- 1
- 2
- 3
- 4
这个接口被大量实现了。
现在,我们需要在接口中新增一个方法 DouBPrint
,其作用是对 Print
方法进行标准化,避免各种不同实现带来的标准差异。于是我们新增一个方法:
public interface IWalterlv
{
void Print(string text);
++ void DouBPrint(string text);
}
- 1
- 2
- 3
- 4
- 5
- 6
然而我们都知道,这样的修改是破坏性的:
- 会使得所有实现这个接口的代码全部失败(无法编译通过,或者运行时抛出异常)
- 我们依然很难将接口的实现标准化,靠文档来规约
默认接口实现
那么现在,我们可以这样来新增此方法:
public interface IWalterlv
{
void Print(string text);
-- void DouBPrint(string text);
++ public void DouBPrint(string text) => Print($"Walterlv 逗比 {text}");
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
在使用此方法来定义此接口中的方法后,那些没来得及实现此方法的类型也可以编译通过并获得标准化的实现。
class Program
{
static void Main(string[] args)
{
IWalterlv walterlv = new Foo();
walterlv.DouBPrint("walterlv");
}
}
public class Foo : IWalterlv
{
public void Print(string text)
{
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
当然,对于 Foo
类型来说,实现也是可以的:
public class Foo : IWalterlv
{
public void Print(string text)
{
}
public void DouBPrint(string text) => Print($"Walterlv 逗比 {text}");
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
静态字段和方法
除此之外,在接口中还可以编写静态字段和静态方法,这可以用来统一接口中的一些默认实现。
意味着,如果类没有实现接口中带有默认实现的方法,那么具有默认的实现;而如果类中打算实现接口中的带有默认实现的方法,那么也可以调用接口中的静态方法来进行实现。
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}");
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
然后,对于实现方,则需要使用接口名来调用接口中的静态成员:
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);
++ }
++ }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
参考资料
- 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://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。
如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。
C# 8.0 中开启默认接口实现的更多相关文章
- C#8.0 中使用默认接口成员更新接口
连载目录 [已更新最新开发文章,点击查看详细] 从 .NET Core 3.0 上的 C# 8.0 开始,可以在声明接口成员时定义实现. 最常见的方案是安全地将成员添加到已经由无数客户端发布并使 ...
- [译]C#8.0中一个使接口更加灵活的新特性-默认接口实现
9月份的时候,微软宣布正式发布C#8.0,作为.NET Core 3.0发行版的一部分.C#8.0的新特性之一就是默认接口实现.在本文中,我们将一起来聊聊默认接口实现. 众所周知,对现有应用程序的接口 ...
- 在Tomcat7.0中设置默认服务器和不加端口名访问
前言 昨天买了域名,服务器,然后搭建了环境,然后想他通过默认的端口,不用端口就访问. 设置WEB项目的欢迎页 在WEB-INF文件夹下有个web.xml文件(最近新建的项目不包含此文件,可以手动新建) ...
- Springboot2.0中jpa默认创建的mysql表为myisam引擎问题
使用Springboot2.0后,使用jpa操作mysql数据库时,默认创建的表的引擎是myisam,myisam是不能加外键的,找了一些资源,最终可以用此方法解决! yml格式: spring: j ...
- IHostingEnvironment VS IHostEnvironment - .NET Core 3.0中的废弃类型
原文: https://andrewlock.net/ihostingenvironment-vs-ihost-environment-obsolete-types-in-net-core-3/ 作者 ...
- C# 8: 默认接口方法
翻译自 John Demetriou 2018年8月4日 的文章 <C# 8: Default Interface Methods>[1],补充了一些内容 C# 8 之前 今天我们来聊一聊 ...
- JDK8.0接口中的默认方法和静态方法
我们在接口中通常定义的方法是抽象方法,即没有方法体,只有返回值类型和方法名:(public abstract) void Method(); 类在实现接口的时候必须重写抽象方法才可以 jdk8中新加的 ...
- Java6.0中Comparable接口与Comparator接口详解
Java6.0中Comparable接口与Comparator接口详解 说到现在,读者应该对Comparable接口有了大概的了解,但是为什么又要有一个Comparator接口呢?难道Java的开发者 ...
- Java 8 接口中的默认方法与静态方法
Java 8 接口中的默认方法与静态方法 1. 接口中的默认方法 允许接口中包含具有具体实现的方法,该方法称"默认方法",默认方法使用用 default 关键字修饰. public ...
随机推荐
- Nginx服务器作反向代理实现内部局域网的url转发配置
情景 由于公司内网有多台服务器的http服务要映射到公司外网静态IP,如果用路由的端口映射来做,就只能一台内网服务器的80端口映射到外网80端口,其他服务器的80端口只能映射到外网的非80端口.非80 ...
- 【Beta】Scrum Meeting 9 & 助教参会记录
目录 前言 任务分配 燃尽图 会议照片 签入记录 上周助教交流总结 Q:项目进度如何? Q:有关commit与issue关联的问题? Q:人员变动后分工的变化情况? Q:接下来还有什么新功能? Q:大 ...
- 【技术博客】Pytorch代码生成
开发组在开发过程中,都不可避免地遇到了一些困难或问题,但都最终想出办法克服了.我们认为这样的经验是有必要记录下来的,因此就有了[技术博客]. Pytorch代码生成经验文档 关于模型代码的生成,主要思 ...
- vmware ubuntu16 启动蓝屏屏幕闪
vmware ubuntu16 启动蓝屏屏幕闪 虚拟机安装了ubuntu16 desktop,没有关闭自动更新: 结果关机虚拟机时出现等5秒更新,类似win10关机更新: 再开机发现就蓝屏了,多次重启 ...
- odoo开发笔记 -- odoo快速开发技巧
1. 需求分析到位 2. 系统对接,角色用例,数据串接 ---确定,轻易不可变更 3. 业务流程拆分细化 出图--开发人员理解的地步 4. 数据模型建立 --对应角色用例 5. 确立开发计划,划分功能 ...
- ByteUtil
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOExceptio ...
- getBrandWCPayRequest 和 chooseWXPay 的区别
getBrandWCPayRequest 和 chooseWXPay 都是发起微信支付请求,chooseWXPay 依赖 http://res.wx.qq.com/open/js/jweixin-1. ...
- elasticsearch中mapping的_source和store的笔记(转)
原文地址: https://www.cnblogs.com/zklidd/p/6149120.html 0.故事引入 无意中看到了ES的mapping中有store字段,作为一个ES菜鸡,有必要对这个 ...
- python -m SimpleHTTPServer搭建简单HTTP服务
PYTHON自带HTTP服务,命令: python -m SimpleHTTPServer 使用上述命令将当前目录发布到8000端口,为当前进行,不是后台运行 指定端口: python -m Simp ...
- 安装centos docker ce
安装centos docker ce 移除旧的版本: $ sudo yum remove docker \ docker-client \ docker-client-latest \ docker- ...