简体   繁体   中英

How to make this method generic?

How can I make this function generic? At the moment this method retrieves a list of type item. What I want to do is to call on this method, with a generic datatype, like Item, Category or Group. All of these has the same property name.

How can I do this?

In logic / service layer with reference to the Data Layer:

public class TaskHandler : ITaskHandler
{
     public async Task<List<newDataType>> Handler(List<Item>() items)
    {
        var newList = new List<newDataType>(); 
        foreach (var item in items)
        {
            newList.Add(new Item
            {
                ID = item.ID,
                Name = item.Status,
                Retrieved = DateTime,
            });
        } 
        return newList ;
    }
}

In dataaccess layer

Datatype1.cs

public class Datatype1
{
    public int ID{ get; set; }
    public string Name{ get; set; }
    public string Group{ get; set; }
}

Datatype2.cs

public class Datatype2
{
    public int ID{ get; set; }
    public string Name{ get; set; }
    public string Group{ get; set; }
}

Datatype3.cs

public class Datatype3
{
    public int ID{ get; set; }
    public string Name{ get; set; }
    public string Group{ get; set; }
}

As all of your types have the same property, you should have a common base-class or interface for them. Then you can easily add a generic constraint to your method:

public async Task<List<T>> Handler<T>(List<Item> items) where T: MyInterface, new()
{
    var newList= new List<T>();
    foreach (var item in items)
    {
        newList.Add(new T
        {
            ID = item.ID,
            Name = item.Status,
            Retrieved = DateTime,
        });
    }

    // ...
}

with

interface MyInterface
{
    // the common properties
}

and

class Item : MyInterface { ...}
class Category : MyInterface { ...}
class Group : MyInterface { ...}

Apart from this I can´t see why your method is async at all, as there´s nothing that can be awaited here.

Your code is async although there is no calls to async. It returns a "message" although there is no reference to any "message" variable. The code is pretty unreadable so its hard to know exactly what you want.

But you need to wrap the method in a generic class. Maybe something like this is what you want.

public class Foo<T> where T : new()
{
    public IEnumerable<T> Handler(IEnumerable<T> items)
    {
        var list = new List<T>();

        foreach (var item in items)
        {
            list.Add(new T
            {
                ID = item.ID,
                Name = item.Status,
                Retrieved = DateTime.Now,
            });
        }

        return list;
    }
}

Wrap your method inside a class which can accept T type (where T : class, new()). and add your method which accept the T - type parameter and return T-type of object.

return message can be newList.

    public class Item
    {
      public int ID { get; set; }
      public string Status { get; set; }
    }

    public interface IRepositoryClass
    {
      int ID { get; set; }
      string Name { get; set; }
      DateTime Retrieved { get; set; }
    }

    public class YourRepositoryClass<T> where T : IRepositoryClass, new()
    { 
     public async Task<IEnumerable<T>> Handler(List<Item> items)
     { 
       var newList= new List<T>();
       foreach (var item in items)
        {
         newList.Add(new T
         {
            ID= item.ID,
            Name= item.Status,
            Retrieved= DateTime,
         });
      }
   return newList; } 
}

If all those classes have the same method named Handler do something like you define a parameter T on the interface level, and your methods can use this parameter in their prototype, so any class that will be implementing this interface will naturally implement the parameter T within its own methods.

interface IBaseInterface<T>
{ 
   Task<List<T>> Handler(List<T> items);
    // the common properties
}

and then do:

public class A : IBaseInterface<A>
{
   public A() { }

   public async Task<List<A>> Handler(List<A> items)
   {
      var newList= new List<A>();
      foreach (var item in items)
      {
          newList.Add(new A
          {
              ID = item.ID,
              Name = item.Status,
              Retrieved = DateTime,
          });
      }
    // ...
    }
}

or totally if you want make that Handler as a generic method you can do something like:

public interface IBaseInterface
{
  //common props
} 
public class DataType1 : IBaseInterface
{
    public DataType1() { }   
}

and

public class Common
{
    public async Task<List<T>> Handler<T>(List<T> items) where T : IBaseInterface
    {
        var newList = new List<T>();
        ....
    }
}

and call it like(just for example) :

public class Consumer
{
    public void Call()
    {
        var param1 = new List<DataType1>();
        var t = new Common().Handler<DataType1>(param1).Result;
    }
}

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