最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#8.0默認(rèn)接口實現(xiàn)的詳細(xì)實例

 更新時間:2021年05月18日 09:07:48   作者:WeihanLi  
Microsoft使用C#8.0發(fā)布了許多新功能,他們引入的主要功能之一是默認(rèn)接口方法。這篇文章主要給大家介紹了關(guān)于C#8.0默認(rèn)接口實現(xiàn)的相關(guān)資料,需要的朋友可以參考下

Intro

C# 8.0 開始引入了默認(rèn)接口實現(xiàn),也就是可以在接口里寫方法實現(xiàn)。

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

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);
}

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

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 方法,并提供了一個默認(rèn)實現(xiàn),在其中一個實現(xiàn)中進(jìn)行了重寫,我們來寫一段代碼測試一下吧

// Cannot resolve symbol 'Fly'
// new Superman().Fly();

IFly fly = new Superman();
fly.Fly();

fly = new MonkeyKing();
fly.Fly();

輸出結(jié)果如下:

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

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

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

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 的方法或字段,則在實現(xiàn)接口的類中就可以通過 IFly.GetDefaultName() 來調(diào)用接口中的方法了,如果是 protected 就只能在實現(xiàn)它的類型中使用,如果要在沒有實現(xiàn)接口的類型中調(diào)用可以聲明為 public 就可以了,下面是在沒有實現(xiàn)接口的類型中調(diào)用的示例:

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

IFly.GetPublicName().Dump();

More

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

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);

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

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

總結(jié)

到此這篇關(guān)于C#8.0默認(rèn)接口實現(xiàn)的文章就介紹到這了,更多相關(guān)C#8.0默認(rèn)接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Unity?數(shù)據(jù)存儲和讀取的方法匯總

    Unity?數(shù)據(jù)存儲和讀取的方法匯總

    這篇文章主要介紹了Unity?數(shù)據(jù)存儲和讀取的方法,本文通過四種方法在 Unity 中實現(xiàn)數(shù)據(jù)存儲和讀取方法的案例內(nèi)容,結(jié)合示例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • WPF實現(xiàn)帶模糊搜索的DataGrid的示例代碼

    WPF實現(xiàn)帶模糊搜索的DataGrid的示例代碼

    這篇文章主要為大家詳細(xì)介紹了WPF如何實現(xiàn)帶模糊搜索的DataGrid,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,需要的可以參考一下
    2023-02-02
  • C#條件拼接Expression<Func<T, bool>>的使用

    C#條件拼接Expression<Func<T, bool>>的使用

    本文主要介紹了C#條件拼接Expression<Func<T, bool>>的使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Unity實現(xiàn)相機截圖功能

    Unity實現(xiàn)相機截圖功能

    這篇文章主要為大家詳細(xì)介紹了Unity實現(xiàn)相機截圖功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • c# 9.0新特性——模塊初始化器

    c# 9.0新特性——模塊初始化器

    這篇文章主要介紹了c# 9.0新特性——模塊初始化器的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c#9.0,感興趣的朋友可以了解下
    2020-11-11
  • c# 值類型實例構(gòu)造器

    c# 值類型實例構(gòu)造器

    CLR總是允許創(chuàng)建值類型的實例。另外值類型不一定需要定義構(gòu)造器,c#編譯器不會為值類型生成默認(rèn)的無參構(gòu)造器
    2012-10-10
  • c#刪除指定文件夾中今天之前的文件

    c#刪除指定文件夾中今天之前的文件

    本文主要介紹了c#刪除指定文件夾中今天之前文件的方法,具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • 淺談C#中的for循環(huán)與foreach循環(huán)

    淺談C#中的for循環(huán)與foreach循環(huán)

    本篇文章主要介紹了C#中的for循環(huán)與foreach循環(huán)的相關(guān)知識,具有很好的參考價值。下面跟著小編一起來看下吧
    2017-05-05
  • c# 網(wǎng)址壓縮簡單實現(xiàn)短網(wǎng)址

    c# 網(wǎng)址壓縮簡單實現(xiàn)短網(wǎng)址

    短網(wǎng)址,忽然一下子就冒出來的東西,長長的一個URL,提交過去,出來就只有短短的一個URL了,看起來似乎挺神奇,其實簡單分析一下,明白其中的原理,也是一件很簡單的事情,需要的朋友可以了解下
    2012-12-12
  • 詳解C# 中Session的用法

    詳解C# 中Session的用法

    這篇文章主要介紹了C# 中Session的用法,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07

最新評論

延吉市| 防城港市| 山阳县| 广宗县| 什邡市| 温泉县| 和顺县| 浮梁县| 宣化县| 普兰店市| 十堰市| 汝南县| 牙克石市| 丹阳市| 新乡市| 横峰县| 新昌县| 农安县| 拜泉县| 泸水县| 公主岭市| 巴彦县| 固阳县| 闸北区| 象山县| 秦皇岛市| 白山市| 海兴县| 海门市| 林芝县| 县级市| 南川市| 额敏县| 洪湖市| 天津市| 禄丰县| 贵港市| 莆田市| 报价| 常宁市| 孟村|