2010-12-07 106 views
0

我正在努力處理下面的代碼。以模板參數傳遞代表作爲參數

我有一個方法查找,這對我來說是泛型的術語,我可以將它用於從相同基類派生的不同類型。在這個方法中,我曾經有一個委託傳遞給FindAll調用。我刪除了這個委託,我試圖將它作爲參數傳遞,所以更多的方法可以使用具有不同過濾條件的Find方法。

問題是,Filter委託必須能夠接受一個Template類型作爲參數,並且編譯器抱怨Find方法的參數不匹配。當我調用Find時,問題發生在FindItems方法內部。

任何想法?非常感謝

delegate bool FindFilter<T_Item>(T_Item item); 

    private List<MailItem> Find<T_Item, T_Adaptor>(T_Adaptor adaptor, MailItemId mailId, FindFilter filter) 
    { 
      List<T_Item> tempList = ((List<T_Item>)(typeof(T_Adaptor).InvokeMember(
        "Load", 
        BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, 
        null, adaptor, 
        new Object[] { null, mailId, null }))); 

      totalItemsFound = tempList.Count; 

      List<T_Item> Items = tempList.FindAll(
          filter() 
         ); 

     List<MailItem> mailItems = new List<MailItem>(); 
     foreach (T_Item itm in Items) 
      mailItems.Add(itm as MailItem); 

     return mailItems; 
    } 

     private static bool FindAssignedItemsOnly<T_Item>(T_Item itm) 
     { 
      MailItem mi = itm as MailItem; 
      if (mi == null) return false; 
      return (mi.StateInd.Code == StateInd.ASSIGNED); 
     } 

    public List<MailItem> FindItems(MailItemId itemId, string mailCategoryCd) 
    { 
     List<MailItem> mailItems = new List<MailItem>(); 

      FindFilter<MailItem> f = FindAssignedItemsOnly; 
      // Problem happens in the line below 
      mailItems = Find<Letter, BasicItemAdapter>(new LetterItemAdapter(), itemId, f); 

     return mailItems; 
    } 
+0

什麼是T_Item,您能發佈更多的代碼嗎? – TalentTuner 2010-12-07 10:46:35

+0

T_Item是模板類型。它可以是從MailItemId派生的任何項目,例如Letter,例如 – Andres 2010-12-07 10:51:42

回答

1

我做了一些改變:

FindItems,改變fFindFilter<BasicItem>

FindFilter<BasicItem> f = FindAssignedItemsOnly; 
    // Problem happens in the line below 
    mailItems = Find<BasicItem, BasicItemAdapter>(new BasicItemAdapter(), itemId, f); 

Find,使用FindFilter泛型類型:

private List<MailItem> Find<T_Item, T_Adaptor>(T_Adaptor adaptor, 
    MailItemId mailId, FindFilter<T_Item> filter) 

並改變了馬在搜索:

List<T_Item> Items = tempList.FindAll(row => filter(row)); 

它編譯;顯然我不能測試它,因爲我不得不發明很多代碼...

+0

好,但現在問題發生在我嘗試調用委託時: 列表 Items = tempList.FindAll(filter(T_Item itm)); 對不起,沒有發佈任何其他代碼,因爲它的巨大 – Andres 2010-12-07 11:08:25

1

我看到的一件事是,在您調用FindAll方法的代碼中,您嘗試使用過濾器變量作爲方法。刪除Parens ...

我一直在做這樣的事情。事實上,我寫了幾個類似於此的通用過程。

查找委託必須匹配謂語,所以任何方法都可以做到這一點。所以舉個例子說你想爲你的過濾器做一些像使用反射一樣瘋狂的東西,你可以做這樣的事情。

public class SimpleFind<T_Adaptor, T_Item> 
{ 
    public T_Adaptor AdapterItem { get; set; } 
    public SimpleFind(T_Adaptor item) 
    { 
     this.AdapterItem = item; 
    } 

    public bool FindMyStuff<T_Item>(T_Item value) 
    { 
     // Place your crazy reflection logic here... 
     if (value.Property == AdapterItem.Property) return true; 
     else return false; 
    } 
} 

那麼你的列表將使用它像這樣直接:

List<T_ITem> items = myItems.Find(new SimpleFind<T_Adaptor, T_Item>(adapterValue).Find); 

,或者在你已經定義的謂詞委託已通過你的方法的情況下:

List<T_ITem> items = myItems.Find(filter); 

我沒有編譯這個,這只是一個假設,這兩個泛型有匹配的值,但我想展示如何擴展它的效果。

但是基於我在代碼中可以看到的內容,如果您在過濾器調用中刪除了父項,過濾器應該可以工作,因爲它是Predicate類型的正確模式中的委託。

0

感謝所有的評論,他們幫了我很多。最後,我剛更改了由Marc建議的lambda調用,因爲並不總是我想過濾:

List<T_Item> Items = tempList.FindAll(
                delegate(T_Item itm) 
                 { 
                  if (filter == null) 
                   return true; 
                  return filter(itm); 
                 } 
               );