C# 8.0 的默認介面方法

  • 2019 年 10 月 31 日
  • 筆記

例子

直接看例子

有這樣一個介面: 

public interface IPerson  2 references  { get; set;  string  Name  2 references  { get; set; }  int  Age

 

然後有三個它的實現類: 

public class Teacher  IPerson  6 references  public string Name { get; set;  3 references  public int Age { get; set; }  I reference  public class Student  IPerson  6 references  public string Name { get; set;  3 references  public int Age { get; set; }  I reference  public class Actor  IPerson  6 references  public string Name { get; set;  3 references  public int Age { get; set; }

 

然後在main方法裡面調用: 

static void Elgin(stringC]  gx•gs  new Teacher();  var teacher =  new Student();  var student =  new Actor();  var actor =  Console . WriteLine( teacher . Name);  Console . WriteLine(student . Name);  Console . WriteLine( actor . Name);

截至目前,程式都可以成功的編譯和運行。 

 

IPerson介面變更 

突然,我想對所有的人類添加一個新的特性,例如,添加一個自我介紹的方法,所以我在IPerson里添加了Introduce()這個方法: 

public interface IPerson  S references  { get; set;  string  Name  3 references  { get; set; }  int  Age  O references  Introduce()  void

 

現在再次Build一下項目,肯定會失敗的: 

irror List  Entire Solution  Code  O CS0535  O CS0535  O CS0535  Description  'Teacher' does not implement interface member 'IPerson.IntroduceO'  'Student' does not implement interface member 'IPerson.IntroduceO'  'Actor' does not implement interface member 'IPerson.IntroduceO'

因為這個方法在三個實現類裡面都沒有實現。 

 

使用默認的實現來更新介面 

如果在C# 8.0以前,我們肯定需要把三個實現類都實現一下這個Introduce() 方法。而在C# 8.0里,我們可以在IPerson介面里做一個默認的方法實現: 

public interface IPerson  7 references  string Name { get; set;  4 references  int Age { get; set; }  O references  Introduce()  void  Console.WriteLine($"I'm  {Name} ,  {Age} years old. " ) ,

 

再次Build之後,您會發現就沒有錯誤了: 

utput  how output from: Build  ConsoleÅppl, on: Debug Any CPU  started: projec  D: OlCorEoI•App1. 811  succeeded. O O

 

而且我們也可以在所有的實現類上正常的調用這個方法: 

static void Mgin(stringC]  gx•gs  var  var  var  var  new Teacher();  teacher =  new Student();  student =  new Actor();  actor =  C] { teacher,  new IPerson  persons =  student,  actor } ;  foreach (var person in persons)  person . Introduce( ) ;

 

I'm  I'm  I'm  years old.  years old.  years old.

我沒有設置任何屬性,但是結果是沒問題的。 

 

但是,不可以直接在實現類上調用該方法,例如這樣寫就會報錯: 

var  var  var  new Teacher();  teacher =  new Student();  student =  new Actor();  actor =  teacher . Introduce( ) ;

這是因為Teacher這個實現類並沒有定義Introduce()這個方法。 

在前面的例子的里,我是通過IPerson介面調用的這個方法,這是沒有問題的,因為IPerson這個介面定義了這個方法。 

 

介面的靜態成員 

上面例子的輸出是這樣的: 

I'm  I'm  I'm  years old.  years old.  years old.

 

而我想讓輸出有默認的名字和年齡,在C# 8.0裡面,我們可以這樣做,添加靜態欄位(field)和靜態方法: 

public interface IPerson  private static string DefaultName -  private static int 20;  O references  "Jane Doe";  SetNameAndAge(string name, int age)  static void  DefaultName  = name;  DefaultAge  = age;  5 references  string Name  get; set;  5 references  int Age { get; set; }  I reference  void Introduce()  Name =  DefaultName;  DefaultAge;  Age -  Console.WriteLine($"I'm {Name},  {Age} years old. " ) ,

實際上這個不會報錯的,出現紅色波浪線的原因可能是因為我的Resharper和VS沒有升級,Build會成功的。 

 

這裡面我做的有點“脫褲子放屁”,但我僅僅是為了展示語言的新特性。 

 

然後在調用的時候,我們可以在IPerson介面上先設置默認值: 

IPerson.SetNameAndAge(  "Nick",  name:  new Teacher();  var teacher =  new Student();  var student =  new Actor()  var actor =  // teacher. Introduce();  38);  age:  C] { teacher,  new IPerson  var persons =  foreach (var person in persons)  person . Introduce( ) ;  student,  actor } ;

 

然後運行: 

I'm Nick, 38 years old.  I'm Nick, 38 years old.  I'm Nick, 38 years old.

可以看到,由於各個實現類都沒有自己的實現,所以都輸出了默認值。 

 

在類上實現介面方法 

在Teacher類上實現Introduce()這個方法: 

 

然後就可以調用Teacher上的Introduce()方法了: 

 

運行程式: 

可以看到無論是通過Teacher類的實例還是通過IPerson介面,最終調用的都是Teacher類實現的Introduce()方法。 

 

更詳細的文檔請點擊這裡查看