在 C# 8.0 中使⽤默认接⼝⽅法更新接⼝

posted at 2020.11.19 13:18 by administrator

.NET Core 3.0 上的 C# 8.0 开始,可以在声明接口成员时定义实现。借助此语言功能,API 作者可以将方法添加到以后版本的接口中,而不会破坏与该接口当前实现的源或二进制文件兼容性。现有的实现继承默认实现 ,最常见的方案是安全地将成员添加到已经由无数客户端发布并使用的接口。

下面举一个具体实例:

软件公司希望拥有现有应用程序的客户采用其库。 他们为使用其库的用户提供最小接口定义供其实现。

以下是客户的接口定义:

        public interface ICustomer {

        IEnumerable PreviousOrders { get; }

        DateTime DateJoined { get; }

        DateTime? LastOrder { get; } string Name { get; }

        IDictionary Reminders { get; } 

 } 

表示订单的第二个接口:

        public interface IOrder {

              DateTime Purchased { get; }

              decimal Cost { get; } 

         }

通过这些接口,团队可以为其用户生成一个库,以便为其客户创造更好的体验。他们的目标是与现有客户建立更深入的关系,并改善他们与新客户的关系。

现在,是时候为下一版本升级库了。其中一个请求的功能可以为拥有大量订单的客户提供忠实客户折扣。 无论客户何时下单,都会应用这一新的忠实客户折扣。该特定折扣是每位客户的财产。ICustomer 的每个实现都可以为忠实 客户折扣设置不同的规则。

添加此功能的最自然方式是使用用于应用任何忠实客户折扣的方法来增强 ICustomer接口。

    默认接口实现使开发人员能够升级接口,同时仍允许任何实现器替代该实现。库的用户可以接受默认实现作为非中断性变更。如果他们的业务规则不同,则可以进行替代。

团队就最有可能的默认实现达成一致:针对客户的忠实客户折扣。

升级应提供用于设置两个属性的功能:符合折扣条件所需的订单数量以及折扣百分比。这使其成为用于默认接口成 员的完美方案。可以向 ICustomer 接口添加方法,并提供最有可能的实现。所有现有的和任何新的实现都可以使用默认实现,或者提供其自己的实现。

首先,将新方法添加到接口,包括方法的主体:

 // Version 1:

 public decimal ComputeLoyaltyDiscount() {

        DateTime TwoYearsAgo = DateTime.Now.AddYears(-2);

        if ((DateJoined < TwoYearsAgo) && (PreviousOrders.Count() > 10)) {

        return 0.10m;

        }

        return 0;

        }

库作者编写了用于检查实现的第一个测试:

          SampleCustomer c = new SampleCustomer(

               "customer one", new DateTime(2010, 5, 31)) {

 Reminders = {

{ new DateTime(2010, 08, 12), "childs's birthday" },

{ new DateTime(1012, 11, 15), "anniversary" } }

                     };

SampleOrder o = new SampleOrder(new DateTime(2012, 6, 1), 5m);

 c.AddOrder(o);

 o = new SampleOrder(new DateTime(2103, 7, 4), 25m);

 c.AddOrder(o);

// Check the discount:

 ICustomer theCustomer = c;

Console.WriteLine($"Current discount: {

           theCustomer.ComputeLoyaltyDiscount()}"); 

注意测试的以下部分:

// Check the discount:

ICustomer theCustomer = c;

Console.WriteLine($"Current discount: {

theCustomer.ComputeLoyaltyDiscount()}"); 

    从 SampleCustomer 到 ICustomer 的强制转换是必需的。 SampleCustomer 类不需要为 ComputeLoyaltyDiscount 提供实现;这由 ICustomer 接口提供。但是, SampleCustomer 类不会从其接口继承成员。 该规则没有更改。 若要调用在接口中声明和实现的任何方法,该变量的类型必须是接口的类型,在本示例中为 ICustomer

Tags: , , , , ,

IT技术

添加评论

  Country flag

biuquote
  • 评论
  • 在线预览
Loading