簡體   English   中英

解決C#中的泛型方法參數

[英]Resolving generic method parameters in C#

我有一個方法,使用完全相同的功能重載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);
    }
}

這是解決問題和重構這個常見代碼的正確方法,還是我在這里遺漏了一些東西?

你可以做這樣的事情

 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

我選擇從來電者垂頭喪氣

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM