简体   繁体   中英

c# replacing methods and classes using generics

This is part of my code in a class (** encloses the things that needs to be polymorped):

public async Task <IEnumerable<**ShopifySharp.Customer**>> GetListAsync(string URLShopify, string AccessToken, ListFilter Filter = null, int MaxReturns = 250)
  {

     var service = new **ShopifySharp.CustomerService**(URLShopify,AccessToken);
     var total = await service.CountAsync(Filter);

     var data = new List<**ShopifySharp.Customer**>();
 var pageOfData = await service.ListAsync(filter);
     data.AddRange(NewItem);
     return data;
  }

I want to call this an get Orders/Customers etc returned (IEnumerable) based on which type it is. If I make a copy of the class and make the changes manually it works. But I want to use the same base class and just use the correct replacements in the derived class. So ShopifySharp.CustomerService and ShopifySharp.Customer should be replaced.

I think generics is the way to go, but struggle with this. So the return parameter has to be changed based on type (Order/Customer etc), and the Service (ShopifySharp.CustomerService), that will be ShopifySharp.OrderService in the case of Order. And the new List (to ShopifySharp.Order) the same as in return value.

In this case Orders and Customers have the same methods. So there will be no errors there. I will use the same in several methods in the class, For example Get and Update.

To clearify:

When I want Customers then the changes will be:

public async Task <IEnumerable<ShopifySharp.Customer>> GetListAsync(string URLShopify, string AccessToken, ListFilter Filter = null, int MaxReturns = 250)

var service = new ShopifySharp.CustomerService(URLShopify,AccessToken);

var data = new List<ShopifySharp.Customer>();

When I want Orders then the changes will be:

public async Task <IEnumerable<ShopifySharp.Order>> GetListAsync(string URLShopify, string AccessToken, ListFilter Filter = null, int MaxReturns = 250)

var service = new ShopifySharp.OrderService(URLShopify,AccessToken);

var data = new List<ShopifySharp.Order>();

The rest of the code will be unchanged since they have the same properties and methods.

Possibly just some generic parameters with the new constraint

The new constraint specifies that a type argument in a generic class declaration must have a public parameterless constructor. To use the new constraint, the type cannot be abstract.

public async Task<IEnumerable<TWhatType>> GetListAsync<TWhatType, TWhatService>(ListFilter filter = null)
   where   TWhatService : new()
{
   var service = new TWhatService();

   var total = await service.CountAsync(filter);
   var data = new List<TWhatType>();

   var pageOfData = await service.ListAsync(filter);

   data.AddRange(pageOfData);

   return data;
}

Note : Because of CountAsync and ListFilter you will also need to constrain by a base class or interface which supports the signatures of anything you want to do in the service.

public interface ISomeService<T>
{
   Task<int> CountAsync(ListFilter filter = null);
   Task<IEnumerable<T>> ListAsync(ListFilter filter = null);
}

...

public async Task<IEnumerable<TWhatType>> GetListAsync<TWhatType, TWhatService>(ListFilter filter = null)
   where TWhatService : ISomeService<TWhatType>, new()
{
    ...

Note : Obviously your service will need to implement this interface as well

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM