原文: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 版本

开启 .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

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

  1. 会使得所有实现这个接口的代码全部失败(无法编译通过,或者运行时抛出异常)
  2. 我们依然很难将接口的实现标准化,靠文档来规约

默认接口实现

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

    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

参考资料


我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

发布了382 篇原创文章 · 获赞 232 · 访问量 47万+

C# 8.0 中开启默认接口实现的更多相关文章

  1. C#8.0 中使用默认接口成员更新接口

    连载目录    [已更新最新开发文章,点击查看详细] 从 .NET Core 3.0 上的 C# 8.0 开始,可以在声明接口成员时定义实现. 最常见的方案是安全地将成员添加到已经由无数客户端发布并使 ...

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

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

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

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

  4. Springboot2.0中jpa默认创建的mysql表为myisam引擎问题

    使用Springboot2.0后,使用jpa操作mysql数据库时,默认创建的表的引擎是myisam,myisam是不能加外键的,找了一些资源,最终可以用此方法解决! yml格式: spring: j ...

  5. IHostingEnvironment VS IHostEnvironment - .NET Core 3.0中的废弃类型

    原文: https://andrewlock.net/ihostingenvironment-vs-ihost-environment-obsolete-types-in-net-core-3/ 作者 ...

  6. C# 8: 默认接口方法

    翻译自 John Demetriou 2018年8月4日 的文章 <C# 8: Default Interface Methods>[1],补充了一些内容 C# 8 之前 今天我们来聊一聊 ...

  7. JDK8.0接口中的默认方法和静态方法

    我们在接口中通常定义的方法是抽象方法,即没有方法体,只有返回值类型和方法名:(public abstract) void Method(); 类在实现接口的时候必须重写抽象方法才可以 jdk8中新加的 ...

  8. Java6.0中Comparable接口与Comparator接口详解

    Java6.0中Comparable接口与Comparator接口详解 说到现在,读者应该对Comparable接口有了大概的了解,但是为什么又要有一个Comparator接口呢?难道Java的开发者 ...

  9. Java 8 接口中的默认方法与静态方法

    Java 8 接口中的默认方法与静态方法 1. 接口中的默认方法 允许接口中包含具有具体实现的方法,该方法称"默认方法",默认方法使用用 default 关键字修饰. public ...

随机推荐

  1. 使用apt-mirror搭建debian镜像源

    debian官方提供了脚本ftpsync来搭建源镜像,而 apt-mirror 是一个更简单便捷的源镜像搭建工具. 安装 apt-mirror sudo apt-get install apt-mir ...

  2. Android Studio 屏幕方向以及UI界面状态的保存

    package com.example.orientation; import android.os.Bundle; import android.util.Log; import android.v ...

  3. JDBC Api详解

    一.什么是JDBC JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Jav ...

  4. BERT模型

    BERT模型是什么 BERT的全称是Bidirectional Encoder Representation from Transformers,即双向Transformer的Encoder,因为de ...

  5. 声源定位之3精读《The Generalized Correlation Method for Estimation of Time Delay》

    2.2.1 标题(2019年9月5日) 估计时间差的广义互相关方法 互相关可以表示两个信号的相似程度. 计算:两个信号循环移位相乘再相加,得到的一组互相关值. 相关函数: 何为广义?通用的框架,可以设 ...

  6. 【转】Python查找某文件夹下的所有excel文件

    # -*- coding: utf-8 -*- # author:baoshan import os dirname = r'D:\0.shenma\01.聊城资料\01.数据资料\02.聊城年鉴数据 ...

  7. 【大数据】Spark On Yarn

    Spark在YARN中有yarn-cluster和yarn-client两种运行模式: I. Yarn client 在yarn-client模式下,Driver运行在Client上,通过Applic ...

  8. Create table as select

    create table xxx as select create table table1 =; 根据table2的表结构,创建tables1 create table table1 as sele ...

  9. cordova 的安桌动画

    1.cordova 的安桌动画cordova plugin add cordova-plugin-lottie-splashscreenhttps://github.com/timbru31/cord ...

  10. 【ARM-Linux开发】Makefile 使用总结

    Makefile 使用总结 1. Makefile 简介 Makefile 是和 make 命令一起配合使用的. 很多大型项目的编译都是通过 Makefile 来组织的, 如果没有 Makefile, ...