2010-12-07 102 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); 
                 } 
               );