成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何在 C# 8 中使用默認接口方法

開發(fā) 后端
C# 8 中新增了一個非常有趣的特性,叫做 默認接口方法 (又稱虛擬擴展方法),這篇文章將會討論 C# 8 中的默認接口方法以及如何使用。

[[378847]]

本文轉(zhuǎn)載自微信公眾號「碼農(nóng)讀書」,作者碼農(nóng)讀書 。轉(zhuǎn)載本文請聯(lián)系碼農(nóng)讀書公眾號。

 C# 8 中新增了一個非常有趣的特性,叫做 默認接口方法 (又稱虛擬擴展方法),這篇文章將會討論 C# 8 中的默認接口方法以及如何使用。

在 C# 8 之前,接口不能包含方法定義,只能在接口中定義方法簽名,還有一個就是接口的成員默認是 public 和 abstract , 在 C# 8 之前,接口不能包含字段,也不能包含private, protected, 或者 internal 的方法成員。如果你在接口中引入了一個新成員,默認情況下你必須更新實現(xiàn)該接口的所有子類。

在 C# 8 中可以在接口定義方法的默認實現(xiàn),而且還可以定義接口成員為 private,protect,甚至是 static,還有一點挺奇葩的,一個接口的 protect 成員是不能被實現(xiàn)類所訪問的,相反,它只能在子接口中被訪問,接口的 virtual 成員可以由派生接口 override,但不能被派生類 override,還有一點請注意,接口目前還不能定義 實例成員。

為什么要使用默認接口方法

所謂的 默認接口方法 指的是接口中定義了一個默認實現(xiàn)的方法, 如果實現(xiàn)該接口的類沒有實現(xiàn)默認接口方法的話,那么這個 默認接口方法 只能從接口上進行訪問,這是一個很有用的特性,因為它可以幫助開發(fā)人員在不破壞現(xiàn)有功能的情況下向接口的未來版本添加新方法。

考慮下面的 ILogger 定義。

  1. public interface ILogger 
  2.    { 
  3.        public void Log(string message); 
  4.    } 

下面的兩個類擴展了ILogger接口并實現(xiàn)了Log()方法。

  1. public class FileLogger : ILogger 
  2.   { 
  3.       public void Log(string message) 
  4.       { 
  5.           //Some code 
  6.       } 
  7.   } 
  8.  
  9.   public class DbLogger : ILogger 
  10.   { 
  11.       public void Log(string message) 
  12.       { 
  13.           //Some code 
  14.       } 
  15.   } 

現(xiàn)在假設(shè)你想在ILogger接口中新增一個方法,該方法接受兩個參數(shù):一個 文本 一個 日志級別,下面的代碼片段展示了日志級別的枚舉類。

  1. public enum LogLevel 
  2.   { 
  3.       Info, Debug, Warning, Error 
  4.   } 

修改后的 ILogger 接口如下:

  1. public interface ILogger 
  2.    { 
  3.        public void Log(string message); 
  4.        public void Log(string message, LogLevel logLevel); 
  5.    } 

好了,現(xiàn)在問題來了,因為 ILogger 中新增了一個 Log 方法,你必須要在所有實現(xiàn)該接口的所有子類中實現(xiàn) Log(string message, LogLevel logLevel) 方法,這就很尷尬了,如果不這樣做的話,編譯器肯定是不會放行的,在現(xiàn)實情況下,這個接口實現(xiàn)類可能在多個 dll 中,甚至在多個團隊中,可想而知,這個工作量是非常大并且非常痛苦的。

默認接口方法案例

這就是 默認接口方法 的應(yīng)用場景,你可以在接口中定義一個默認方法是實現(xiàn),如下代碼所示:

  1. public interface ILogger 
  2.   { 
  3.       public void Log(string message); 
  4.  
  5.       public void Log(string message, LogLevel logLevel) 
  6.       { 
  7.           Console.WriteLine("Log method of ILogger called."); 
  8.           Console.WriteLine("Log Level: "+ logLevel.ToString()); 
  9.           Console.WriteLine(message); 
  10.       } 
  11.   } 

這個時候,實現(xiàn) ILogger 接口的子類可以不實現(xiàn)新的 Log(string message, LogLevel logLevel) 方法,因此下面的代碼也是跑的通的,編譯器不會拋出任何錯誤。

  1. public class FileLogger : ILogger 
  2.    { 
  3.        public void Log(string message) 
  4.        { 
  5.            //Some code 
  6.        } 
  7.    } 
  8.  
  9.    public class DbLogger : ILogger 
  10.    { 
  11.        public void Log(string message) 
  12.        { 
  13.            //Some code 
  14.        } 
  15.    } 

默認接口方法不能被繼承

現(xiàn)在創(chuàng)建一個 FileLogger 類實例,然后直接調(diào)用新的帶參數(shù)的 Log() 方法,如下代碼所示:

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

從上面圖可看出 默認接口方法 不能被子類繼承,換句話說,子類根本就不知道接口中還有帶參數(shù)的 Log() 方法。

默認接口方法和菱形問題

現(xiàn)在有一個非常重要的問題,默認接口方法如何避免 菱形問題?換句話說就是 接口的 多繼承 問題,考慮下面的代碼清單。

  1. public interface A 
  2.     { 
  3.         public void Display(); 
  4.     } 
  5.  
  6.     public interface B : A 
  7.     { 
  8.         public void Display() 
  9.         { 
  10.             Console.WriteLine("Interface B."); 
  11.         } 
  12.     } 
  13.  
  14.     public interface C : A 
  15.     { 
  16.         public void Display() 
  17.         { 
  18.             Console.WriteLine("Interface C."); 
  19.         } 
  20.     } 
  21.  
  22.     public class MyClass : B, C 
  23.     { 
  24.  
  25.     } 

當(dāng)編譯上面代碼時,會拋出一個編譯錯誤,說 MyClass 沒有實現(xiàn) A.Display() 方法,解決這個問題很簡單,在 MyClass 中實現(xiàn)一下接口方法就可以了,如下代碼所示:

  1. public interface A 
  2.     { 
  3.         public void Display(); 
  4.     } 
  5.     public interface B : A 
  6.     { 
  7.         public void Display() 
  8.         { 
  9.             Console.WriteLine("Interface B."); 
  10.         } 
  11.     } 
  12.     public interface C : A 
  13.     { 
  14.         public void Display() 
  15.         { 
  16.             Console.WriteLine("Interface C."); 
  17.         } 
  18.     } 
  19.     public class MyClass : B, C 
  20.     { 
  21.         public void Display() 
  22.         { 
  23.             Console.WriteLine("MyClass."); 
  24.         } 
  25.     } 

接下來就可以生成 MyClass 實例了,然后再調(diào)用 Display() 方法,如下代碼所示:

  1. static void Main(string[] args) 
  2.         { 
  3.             A obj = new MyClass(); 
  4.             obj.Display(); 
  5.             Console.Read(); 
  6.         } 

現(xiàn)在問題來了,到底是哪一個 Display() 方法被調(diào)用了呢?為了避免歧義,C# 將會使用最近覆蓋規(guī)則,即 Class.Display() 方法被最先調(diào)用。

抽象類 VS 接口

到這里,我想你肯定有疑問,抽象類 和 接口 是不是很相似了,甚至可以互換了?雖然抽象類和接口現(xiàn)在看起來在很多方面都很相似,但兩者之間還是有微妙的區(qū)別的,具體如下:

  • 抽象類可以有實例成員,接口則不能。
  • 抽象類不能多繼承,接口還是可以的。

默認接口方法 允許開發(fā)人員利用 trait 編程技術(shù),該技術(shù)可以讓那些附屬于該方法的不相關(guān)類型得以繼續(xù)使用,可能你有點懵,我舉個例子:假設(shè)你構(gòu)建好了一個dll,被很多的開發(fā)人員所使用,現(xiàn)在你要發(fā)布該 dll 的新版本,比如說往接口中添加了新方法,這個時候你可以定義默認實現(xiàn),這樣就可以對已使用的開發(fā)者進行無感升級。

譯文鏈接:https://www.infoworld.com/article/3455239/how-to-use-default-interface-methods-in-csharp-8.html

 

責(zé)任編輯:武曉燕 來源: 碼農(nóng)讀書
相關(guān)推薦

2021-02-01 12:36:59

C# Channels存儲

2021-01-19 05:30:55

C# 8異步流IEnumerable

2021-01-18 05:18:18

C# 8模式C# 7

2021-01-22 05:53:08

C# IndexRange

2020-12-31 07:31:10

C# 反射數(shù)據(jù)

2021-03-07 16:37:52

C#應(yīng)用程序

2025-05-12 03:10:00

接口方法代碼

2022-05-17 08:25:10

TypeScript接口前端

2009-08-04 10:29:06

在C#中使用存儲過程

2021-11-25 00:04:16

C# 插值字符串

2023-01-28 17:41:07

Java代碼

2009-08-14 17:58:05

C#接口方法

2019-04-23 15:20:26

JavaScript對象前端

2018-08-03 08:37:31

設(shè)計模式IT項目GDPR

2009-04-03 13:20:05

C#擴展方法調(diào)用

2009-03-18 09:15:34

UndoRedoC#

2022-06-23 08:00:53

PythonDateTime模塊

2021-06-09 09:36:18

DjangoElasticSearLinux

2021-03-09 07:27:40

Kafka開源分布式

2015-08-27 09:46:09

swiftAFNetworkin
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: www.亚洲| heyzo在线 | 激情婷婷 | 黄色网址免费在线观看 | 国产精品久久久久久久久久久久 | 成人国产精品久久 | 日本电影韩国电影免费观看 | 亚洲免费网站 | 日韩三级在线 | www97影院 | 日韩不卡一区二区三区 | 日韩精品在线观看视频 | 亚洲精品成人免费 | 99久久精品视频免费 | 午夜日韩 | 91免费观看 | 免费黄色大片 | 日韩成人在线免费视频 | 久久www免费视频 | 国产精品精品视频一区二区三区 | 日韩精品一区中文字幕 | 最新国产精品精品视频 | 国产精品成人69xxx免费视频 | 国产精品国产精品国产专区不蜜 | 成人在线视频看看 | 91成人免费看 | 国产清纯白嫩初高生在线播放视频 | av电影一区二区 | 免费黄视频网站 | 天天躁日日躁性色aⅴ电影 免费在线观看成年人视频 国产欧美精品 | 国产精品一区二区三 | 99久久99久久精品国产片果冰 | 欧美一区视频 | 久久久精 | 亚洲综合大片69999 | 五月天天丁香婷婷在线中 | 岛国毛片 | 亚洲性爰 | 婷婷色在线 | 午夜视频大全 | 中文一区二区 |