C # 8.0 in the default update interface interface members

Starting on C # 8.0 .NET Core 3.0, you can define realize when you declare interface member. The most common solution is to add members to safely and has been published interfaces used by numerous clients.

In this tutorial, you will learn:

  • By using the Add method to achieve safely expansion interface.
  • Create a parameterized to achieve in order to provide greater flexibility.
  • So realized can provide a more specific implementation as an alternative.

 

01 Prerequisites

The computer needs to be set to run .NET Core, including C # 8.0 compiler preview. From the  Visual Studio 2019  or the latest  .NET Core 3.0 Preview SDK  to start, you can use C # 8.0 compiler preview. From .NET Core 3.0 Preview 4 members began to provide the default interface.

02 Overview of the program
This tutorial library version from the customer relationship start 1. It can be  an example repository on GitHub to get the access application. The company hopes to generate this library have existing applications customers use their library. They provide a minimum interface definition for its implementation for users to use their library. The following is the customer's interface definition:
public interface ICustomer
{
    IEnumerable<IOrder> PreviousOrders { get; }

    DateTime DateJoined { get; }
    DateTime? LastOrder { get; }
    string Name { get; }
    IDictionary<DateTime, string> Reminders { get; }
}

They define the express orders of the second interface:

public interface IOrder
{
    DateTime Purchased { get; }
    decimal Cost { get; }
}

Through these interfaces, the team can generate a library for its users, in order to create a better experience for their customers. Their goal is to build deeper relationships with existing customers and improve their relationships with new customers.

Now, it's time to upgrade to the next version of the library. One of the requested functionality can provide loyal customers discounts for customers with large orders. Regardless of when the customer orders, will be applied to this new loyal customer discount. The discount is specific to each customer's property. Each implementation can be thought of ICustomer loyal customers discounts set different rules.

Adding this feature the most natural way is to use the method for applying any discounts to loyal customers enhanced  ICustomer interfaces. The design proposal has attracted the attention of experienced developers: "! Once published, the interface is fixed  This is a groundbreaking change!" C  # 8.0 adds the default interface  used to upgrade the interface. Library authors can add new members to the interface and provides default implementations for these members.

The default interface enables developers to upgrade the interface, while still allowing for any implement an alternative to the implementation. The user can accept the default library implemented as a non-disruptive change. If their business rules are different, it can be substituted.

03 members using the default interface upgrade

Team most likely to default implementation of the agreement: for customers loyal customer discount.

Upgrading should be provided for setting two properties of functions: in line with the volume of orders and the discount percentage discount required conditions. This makes it the perfect solution for the default interface members. You can add to the ICustomer interface method, and the most likely to achieve. All existing and any new implementations can use the default implementation, or provide their own implementation.

First, add a new method to implementation:

// Version 1:
public decimal ComputeLoyaltyDiscount()
{
    DateTime TwoYearsAgo = DateTime.Now.AddYears(-2);
    if ((DateJoined < TwoYearsAgo) && (PreviousOrders.Count() > 10))
    {
        return 0.10m;
    }
    return 0;
}

Library authors wrote the first test used to check the implementation:

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); // 检查折扣 ICustomer theCustomer = c; Console.WriteLine($"Current discount: {theCustomer.ComputeLoyaltyDiscount()}");

Note the following tests:

// 检查折扣
ICustomer theCustomer = c;
Console.WriteLine($"Current discount: {theCustomer.ComputeLoyaltyDiscount()}");

From  SampleCustomer the  ICustomer cast it is necessary. SampleCustomer Class does not need to  ComputeLoyaltyDiscount provide an implementation; This is done by  ICustomer providing an interface. However, the SampleCustomer class does not inherit the interface from among its members. The rules have not changed. To call any of the methods declared in the interface and implementation, type of the variable must be of type interface, as in this example  ICustomer.

04 offers parametric
This is a good beginning. However, the default realize there are too many restrictions. Many users of this system may choose to purchase a different threshold number of different length or different discount percentage of membership. By providing a method for setting these parameters, we can provide a better experience for more customers to upgrade. Let's add a static method that can set the default implementation of the three control parameters:
// Version 2:
public static void SetLoyaltyThresholds(TimeSpan ago, int minimumOrders = 10, decimal percentageDiscount = 0.10m)
{
    length = ago;
    orderCount = minimumOrders;
    discountPercent = percentageDiscount;
}
private static TimeSpan length = new TimeSpan(365 * 2, 0,0,0); // 2年 private static int orderCount = 10; private static decimal discountPercent = 0.10m; public decimal ComputeLoyaltyDiscount() { DateTime start = DateTime.Now - length; if ((DateJoined < start) && (PreviousOrders.Count() > orderCount)) { return discountPercent; } return 0; }

This small code fragment shows many new language features. Interface can now include static members, including fields and methods. Also enable different access modifiers. Other fields are special, the new method is public. Interface allows members to use any modifier.

Loyal customer discount is calculated using the conventional formula but different parameters of the application does not need to provide a custom implementation; they can be set through the static method arguments. For example, the following code sets the "customer appreciation" to award any customer to become a member of more than one month:

ICustomer.SetLoyaltyThresholds(new TimeSpan(30, 0, 0, 0), 1, 0.25m);
Console.WriteLine($"Current discount: {theCustomer.ComputeLoyaltyDiscount()}");
05 default implementation extension

Currently added code to provide a convenient implementation, a user may need similar projects default implementation of the program, or to provide a set of rules irrelevant. For the last feature, let us look a little refactoring code to achieve the user may need to be generated based on the default implementation of the program.

Suppose a customer wants to attract new startups. They offer a 50% discount for the first order for new customers,  but existing customers will get the standard discount. Library authors need to be moved to the default implementation methods to achieve this interface of any class can reuse code in its implementation. The default implementation of the interface members also call this sharing method: protected static 

public decimal ComputeLoyaltyDiscount() => DefaultLoyaltyDiscount(this);
protected static decimal DefaultLoyaltyDiscount(ICustomer c)
{
    DateTime start = DateTime.Now - length;

    if ((c.DateJoined < start) && (c.PreviousOrders.Count() > orderCount))
    {
        return discountPercent;
    }
    return 0;
}

In the realization of a class that implements this interface, the substitution can call the static helper methods, and extend the logic to provide a "new customer" discount:

public decimal ComputeLoyaltyDiscount()
{
   if (PreviousOrders.Any() == false)
        return 0.50m;
    else
        return ICustomer.DefaultLoyaltyDiscount(this);
}

We may be located in [Example repository on GitHub] to view the entire complete code (can be  an example repository on GitHub to get the access application).

These new features mean that when these new members have reasonable default implementation, the interface can be safely updated. The interface is designed to express the concept of a single function may be implemented in a plurality of classes. As a result, when the discovery of new functions required for the same concept can be more easily upgrade the interface definition.

Guess you like

Origin www.cnblogs.com/SavionZhang/p/11203119.html