由于乔恩斯基特在this问题的答案,我有以下工作:的MethodInfo,createDelegate方法和泛型方法
public delegate BaseItem GetItemDelegate(Guid itemID);
public static class Lists
{
public static GetItemDelegate GetItemDelegateForType(Type derivedType)
{
MethodInfo method = typeof(Lists).GetMethod("GetItem");
method = method.MakeGenericMethod(new Type[] { derivedType });
return (GetItemDelegate)Delegate.CreateDelegate(typeof(GetItemDelegate), method);
}
public static T GetItem<T>(Guid itemID) where T : class { // returns an item of type T ... }
}
public class DerivedItem : BaseItem { }
// I can call it like so:
GetItemDelegate getItem = Lists.GetItemDelegateForType(typeof(DerivedItem));
DerivedItem myItem = getItem(someID); // this works great
当我尝试运用同样的事情的方法具有不同的返回类型和过载(那些是我能想出的唯一区别),我得到一个恼人的“ArgumentException:错误绑定到目标方法。”致电CreateDelegate
。以下是一个可以获取错误的实例,只需复制/粘贴到控制台应用程序中。
public delegate IEnumerable<BaseItem> GetListDelegate();
public class BaseItem { }
public class DerivedItem : BaseItem { }
public static class Lists
{
public static GetListDelegate GetListDelegateForType(Type itemType)
{
MethodInfo method = typeof(Lists).GetMethod("GetList", Type.EmptyTypes); // get the overload with no parameters
method = method.MakeGenericMethod(new Type[] { itemType });
return (GetListDelegate)Delegate.CreateDelegate(typeof(GetListDelegate), method);
}
// this is the one I want a delegate to, hence the Type.EmptyTypes above
public static IEnumerable<T> GetList<T>() where T : class { return new List<T>(0); }
// not the one I want a delegate to; included for illustration
public static IEnumerable<T> GetList<T>(int param) where T : class { return new List<T>(0); }
public static Type GetItemType()
{ // this could return any type derived from BaseItem
return typeof(DerivedItem);
}
}
class Program
{
static void Main(string[] args)
{
Type itemType = Lists.GetItemType();
GetListDelegate getList = Lists.GetListDelegateForType(itemType);
IEnumerable<BaseItem> myList = (IEnumerable<BaseItem>)getList();
}
}
正如上面提到的,我能看到的唯一区别是:
- 不同的返回类型(
T
作品,IEnumerable<T>
不)[编辑:这是不对的,第一个版本的用途BaseItem
,而不是T
;哎呀] - 重载(
GetItem
没有超载,GetList
有几个,我只需要在委托GetList()
没有PARAMS
UPDATE1:萨姆帮我找出一些问题,如果的返回类型委托是通用的(例如IEnumerable<BaseItem>
),当我尝试交换基类/派生类型时,它会窒息。有没有什么办法可以声明我的GetList
方法如下?我需要能够指示继承自BaseItem
,但是如果我那么它可以为我工作。
public static IEnumerable<BaseItem> GetList<T>() where T : class
另一种选择是“通用化”我的委托声明。我可以找到的所有示例都使用通用参数,而不是返回类型。我如何做到这一点(它抛出一个编译器错误原因T
是不确定的,它不会让我用where
约束):
public delegate IEnumerable<T> GetListDelegate();
在发布之前的所有阅读中,我知道类型不匹配是此异常的一个常见原因。我在上面每个例子中的返回调用中设置了一个断点,并且在每种情况下变量方法的类型看起来几乎相同。我什么都看不到。只是想我会添加那个珍闻。 – sliderhouserules 2010-01-14 04:20:53
为什么这会变成社区维基? – sliderhouserules 2010-01-14 08:03:13
哇,你编辑自己的帖子够了,它会自动变成一个维基?这是该死的愚蠢。 – sliderhouserules 2010-01-14 08:18:12