日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C# 8.0 默认接口实现

發布時間:2023/12/4 C# 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C# 8.0 默认接口实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

C# 8.0 默認接口實現

Intro

C# 8.0 開始引入了默認接口實現,也就是可以在接口里寫方法實現。

在之前的版本中接口上是沒有辦法定義實現的,方法也都是 public 的,除了接口和屬性之外是不能定義其他數據的,這也意味著,接口從一開始就要設計得比較好,否則在已有接口里增加新方法的時候其實現就必須要修改,否則就會編譯失敗,默認接口實現使得可以不造成破壞性變更的前提下在接口中新增加方法,只需要在接口中提供一個默認的實現即可。

Sample

下面我們來看一個示例吧:

internal?interface?IFly {string?Name?{?get;?} } internal?class?Superman?:?IFly {public?string?Name?=>?nameof(Superman); } internal?class?MonkeyKing?:?IFly {public?string?Name?=>?nameof(MonkeyKing); }

這是一個基本的接口定義,并提供了兩個實現,緊接著我們來為接口新增一個方法,

internal?interface?IFly {string?Name?{?get;?}void?Fly()?=>?Console.WriteLine($"{Name.GetValueOrDefault((DefaultName))}?is?flying"); }internal?class?Superman?:?IFly {public?string?Name?=>?nameof(Superman);public?void?Test(){((IFly)?this).Fly();Console.WriteLine(Name);} }internal?class?MonkeyKing?:?IFly {public?string?Name?=>?nameof(MonkeyKing);public?void?Fly(){Console.WriteLine($"I'm?{Name},?I'm?flying");} }

我們在接口里增加了一個 Fly 方法,并提供了一個默認實現,在其中一個實現中進行了重寫,我們來寫一段代碼測試一下吧

//?Cannot?resolve?symbol?'Fly' //?new?Superman().Fly();IFly?fly?=?new?Superman(); fly.Fly();fly?=?new?MonkeyKing(); fly.Fly();

輸出結果如下:

Superman?is?flying I'm?MonkeyKing,?I'm?flying IFly

上面的示例中 Superman 沒有定義 Fly 這個方法,是不能直接調用 Fly 方法的,需要先轉成 IFly 接口然后再調用,此時方法實現是在接口里定義的邏輯,而 MonkeyKing 實現了 Fly 方法,所以會使用它自己的 Fly 實現,如上面所示。

除了上面的基本用法之外,現在可以在接口里定義靜態字段靜態方法來實現更好的方法復用,我們在上面的示例里演示一下,修改后的示例如下:

internal?interface?IFly {private?const?string?DefaultName?=?nameof(IFly);protected?static?string?GetDefaultName()?=>?DefaultName;public?static?string?GetPublicName()?=>?DefaultName;//?Interface?cannot?contain?instance?fields//?private?string?name?=?"";string?Name?{?get;?}void?Fly()?=>?Console.WriteLine($"{Name.GetValueOrDefault((DefaultName))}?is?flying"); }internal?class?MonkeyKing?:?IFly {public?string?Name?=>?nameof(MonkeyKing);public?void?Fly(){Console.WriteLine($"I'm?{Name},?I'm?flying,?DefaultName:{IFly.GetDefaultName()}");} }

如果定義了 protected static 的方法或字段,則在實現接口的類中就可以通過 IFly.GetDefaultName() 來調用接口中的方法了,如果是 protected 就只能在實現它的類型中使用,如果要在沒有實現接口的類型中調用可以聲明為 public 就可以了,下面是在沒有實現接口的類型中調用的示例:

//?Cannot?access?protected?method?'GetDefaultName'?here //?IFly.GetDefaultName().Dump();IFly.GetPublicName().Dump();

More

雖然現在可以這樣用,但我個人還是推薦沿用之前的接口用法,不要輕易使用這個特性,提前設計提前規劃才是正道,不要想著事后補償,感覺這個特性比較合適的一個使用場景是現在基于接口的擴展方法,擴展方法作為一個接口的默認實現,具體類可以重寫這個實現,使用示例如下:

Task<bool>?SaveProperties(int?id,?Dictionary<string,?object>?properties) {if?(properties?is?null?||?properties.Count?==?0)?return?Task.FromResult(false);var?json?=?JsonConvert.SerializeObject(properties.Select(p?=>?new?PropertyModel(){PropertyName?=?p.Key,PropertyValue?=?p.Value?.ToString()}));return?SaveProperties(id,?json); }Task<bool>?SaveProperties(int?id,?string?properties);

在之前的版本中,我一般都是把上面的方法作為一個擴展方法來用,有個默認接口實現之后也可以考慮加一個默認實現(僅限于業務代碼中,針對類庫代碼,感覺還是越干凈越好)

References

  • https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/default-interface-methods-versions

  • https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#default-interface-methods

  • https://github.com/WeihanLi/SamplesInPractice/blob/master/CSharp9Sample/DefaultInterfaceImplement.cs

總結

以上是生活随笔為你收集整理的C# 8.0 默认接口实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。