解决C#中的泛型方法参数

时间:2016-02-25 18:42:08

标签: c# wsdl

我有一个方法,它使用完全相同的功能重载3次,唯一的变化是一个参数,它是一个具体类型的列表。

private void _doWork(string name, List<TargetItem> members)
{
    foreach(var member in members)
    {
      _doExtraWork(member.TimeToWork);
    }
}

private void _doWork(string name, List<NonTargetItem> members)
{
    foreach(var member in members)
    {
      _doExtraWork(member.TimeToWork);
    }
}

这里要知道的是列表中的2个类来自WSDL定义。迭代中的操作是在共享成员上,因为它们派生自相同的基类,但是这个继承是在WSDL中抽象的。

我试图做这样的事情 -

private void _doWork<T>(string name, List<T> members)
{
    var commonList = new List<>(); /// what type should I use here?

    if(typeof (T) == typeof(TargetItem))
    {
      commonList = members; // assume equal to means copying members to commonList with type conversion
    }
    if(typeof (T) == typeof(NonTargetItem))
    {
      commonList = members;
    }
    foreach(var member in commonList)
    {
      _doExtraWork(member.TimeToWork);
    }
}

这是解决问题并重构此常用代码的正确方法,还是我在这里遗漏了一些内容?

2 个答案:

答案 0 :(得分:1)

你可以做这样的事情

 private static void _doWork<T>(string name, T members) where T : IEnumerable
{
     foreach(var member in members)
    {
      _doExtraWork(member.TimeToWork);
    }
}

在您的通话代码中

_doWork("sdfsd", new List<TargetItem>()); // here just as example I am passing new instance
_doWork("sdfsd", new List<NonTargetItem>()); // here just as example I am passing new instance

由于List<T>的类型为IEnumerable<T>,因此其类型为IEnumerable。您可以在通用函数中添加IEnumerable泛型constaints。这样,您就不必在通用函数中进行类型检查。

如果要实现单个doExtraWork方法,则需要为TargetItem和NonTargetItem提供CommonType。您可以使用下面的适配器模式解决此问题

Interface IItem
{
 int TimeToWorkAdapt {get;}
}

//Now create a wrapper class for TargetItem and NonTargetItem

Class TargetItemAdapt : TargetItem,IItem
{
   public int TimeToWorkAdapt 
       {
           get { base.TimeToWork;}    
       }
}

Class NonTargetItemAdapt : NonTargetItem,IItem
{
   public int TimeToWorkAdapt 
       {
           get { base.TimeToWork;}    
       }
}
 // write a generic function which wrap calls to your do extra work method but with generic constriants to interface
private static void _doExtraWork<T>(T members) where T : IItem
    {
          _doExtraWork(member.TimeToWorkAdapt);

    }
// In your Main program...now use our wrapper classes

_doWork("sdfsd", new List<TargetItemAdapt>()); // here just as example I am passing new instance
_doWork("sdfsd", new List<NonTargetItemAdapt>()); // here just as example I am passing new instance

答案 1 :(得分:0)

我选择从来电者垂头丧气

_doWork("Target", Object.TargetItems.ToList<BaseClass>());
_doWork("NonTarget", Object.NonTargetItems.ToList<BaseClass>());