欢迎来到雅狐站长网!
兔子CDN

C#教程

当前位置:主页 > 软件教程 > C#教程 >

在C# 8中如何使用默认接口方法详解

时间:2021-04-27 14:50:52|栏目:C#教程|点击:

前言

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

在 C# 8 之前,接口不能包含方法定义,只能在接口中定义方法签名,还有一个就是接口的成员默认是 public 和 abstract , 在 C# 8 之前,接口不能包含字段,也不能包含private, protected, 或者 internal 的方法成员。如果你在接口中引入了一个新成员,默认情况下你必须更新实现该接口的所有子类。

在 C# 8 中可以在接口定义方法的默认实现,而且还可以定义接口成员为 private,protect,甚至是 static,还有一点挺奇葩的,一个接口的 protect 成员是不能被实现类所访问的,相反,它只能在子接口中被访问,接口的 virtual 成员可以由派生接口 override,但不能被派生类 override,还有一点请注意,接口目前还不能定义 实例成员。

为什么要使用默认接口方法

所谓的 默认接口方法 指的是接口中定义了一个默认实现的方法, 如果实现该接口的类没有实现默认接口方法的话,那么这个 默认接口方法 只能从接口上进行访问,这是一个很有用的特性,因为它可以帮助开发人员在不破坏现有功能的情况下向接口的未来版本添加新方法。

考虑下面的 ILogger 定义。

 public interface ILogger
 {
 public void Log(string message);
 }

下面的两个类扩展了ILogger接口并实现了Log()方法。

 public class FileLogger : ILogger
 {
 public void Log(string message)
 {
  //Some code
 }
 }

 public class DbLogger : ILogger
 {
 public void Log(string message)
 {
  //Some code
 }
 }

现在假设你想在ILogger接口中新增一个方法,该方法接受两个参数:一个 文本 一个 日志级别,下面的代码片段展示了日志级别的枚举类。

 public enum LogLevel
 {
 Info, Debug, Warning, Error
 }

修改后的 ILogger 接口如下:

 public interface ILogger
 {
 public void Log(string message);
 public void Log(string message, LogLevel logLevel);
 }

好了,现在问题来了,因为 ILogger 中新增了一个 Log 方法,你必须要在所有实现该接口的所有子类中实现 Log(string message, LogLevel logLevel) 方法,这就很尴尬了,如果不这样做的话,编译器肯定是不会放行的,在现实情况下,这个接口实现类可能在多个 dll 中,甚至在多个团队中,可想而知,这个工作量是非常大并且非常痛苦的。

默认接口方法案例

这就是 默认接口方法 的应用场景,你可以在接口中定义一个默认方法是实现,如下代码所示:

 public interface ILogger
 {
 public void Log(string message);

 public void Log(string message, LogLevel logLevel)
 {
  Console.WriteLine("Log method of ILogger called.");
  Console.WriteLine("Log Level: "+ logLevel.ToString());
  Console.WriteLine(message);
 }
 }

这个时候,实现 ILogger 接口的子类可以不实现新的 Log(string message, LogLevel logLevel) 方法,因此下面的代码也是跑的通的,编译器不会抛出任何错误。

 public class FileLogger : ILogger
 {
 public void Log(string message)
 {
  //Some code
 }
 }

 public class DbLogger : ILogger
 {
 public void Log(string message)
 {
  //Some code
 }
 }

默认接口方法不能被继承

现在创建一个 FileLogger 类实例,然后直接调用新的带参数的 Log() 方法,如下代码所示:

FileLogger fileLogger = new FileLogger();
fileLogger.Log("This is a test message.", LogLevel.Debug);

在C# 8中如何使用默认接口方法详解

从上面图可看出 默认接口方法 不能被子类继承,换句话说,子类根本就不知道接口中还有带参数的 Log() 方法。

默认接口方法和菱形问题

现在有一个非常重要的问题,默认接口方法如何避免 菱形问题?换句话说就是 接口的 多继承 问题,考虑下面的代码清单。

 public interface A
 {
  public void Display();
 }

 public interface B : A
 {
  public void Display()
  {
   Console.WriteLine("Interface B.");
  }
 }

 public interface C : A
 {
  public void Display()
  {
   Console.WriteLine("Interface C.");
  }
 }

 public class MyClass : B, C
 {

 }

当编译上面代码时,会抛出一个编译错误,说 MyClass 没有实现 A.Display() 方法,解决这个问题很简单,在 MyClass 中实现一下接口方法就可以了,如下代码所示:

 public interface A
 {
  public void Display();
 }
 public interface B : A
 {
  public void Display()
  {
   Console.WriteLine("Interface B.");
  }
 }
 public interface C : A
 {
  public void Display()
  {
   Console.WriteLine("Interface C.");
  }
 }
 public class MyClass : B, C
 {
  public void Display()
  {
   Console.WriteLine("MyClass.");
  }
 }

上一篇:C# 中如何使用Thread

栏    目:C#教程

下一篇:c# 使用谷歌身份验证GoogleAuthenticator的示例

本文标题:在C# 8中如何使用默认接口方法详解

本文地址:http://www.cnzzww.cn/ccjiaocheng/56506.html

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ: | 邮箱:111#qq.com(#换成@)

Copyright © 2015-2020 雅狐站长网 版权所有 苏ICP备20040415号