Thanks Jon Skeet answer in this question I have the following working:
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 {
}
public class DerivedItem : BaseItem { }
GetItemDelegate getItem = Lists.GetItemDelegateForType(typeof(DerivedItem));
DerivedItem myItem = getItem(someID);
When I try to apply the same thing to a method with a different return type and overloads (these are the only differences that I can come up with), I get the annoying "ArgumentException: Target Method Binding Error". when called CreateDelegate. Below is a working example that gets an error, just copy / paste into the console application.
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);
method = method.MakeGenericMethod(new Type[] { itemType });
return (GetListDelegate)Delegate.CreateDelegate(typeof(GetListDelegate), method);
}
public static IEnumerable<T> GetList<T>() where T : class { return new List<T>(0); }
public static IEnumerable<T> GetList<T>(int param) where T : class { return new List<T>(0); }
public static Type GetItemType()
{
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();
}
}
As mentioned above, the only differences that I see are the following:
- Different Type of Return Value (
Tworks, IEnumerable<T>does not) [EDIT: this is wrong, the first version uses BaseItem, not T; oops] - (
GetItem , GetList , GetList()
Update1: . (, IEnumerable<BaseItem>), , / . GetList, ? , T BaseItem, , .
public static IEnumerable<BaseItem> GetList<T>() where T : class
"" . , , params, . ( T undefined, where):
public delegate IEnumerable<T> GetListDelegate();