EDIT: Highlight difficulties with virtual and/or value-type methods
Can you create a delegate of an instance method without specifying the instance at creation time? In other words, can you create a "static" delegate that takes as it's first parameter the instance the method should be called on?
For example, how can I construct the following delegate using reflection?
Func<int, string> = i=>i.ToString();
I'm aware of the fact that I can use methodInfo.Invoke, but this is slower, and does not check for type-correctness until it is called.
When you have the MethodInfo
of a particular static method, it is possible to construct a delegate using Delegate.CreateDelegate(delegateType, methodInfo)
, and all parameters of the static method remain free.
As Jon Skeet pointed out, you can simply apply the same to make an open delegate of an instance method if the method is non-virtual on a reference type. Deciding which method to call on a virtual method is tricky, so that's no so trivial, and value-types look like they don't work at all.
EDIT: For value types, CreateDelegate
exhibits really weird behavior:
var func37 = (Func<CultureInfo,string>)(37.ToString);
var toStringMethod = typeof(int).GetMethod("ToString", BindingFlags.Instance | BindingFlags.Public, null, new Type[] {typeof(CultureInfo) }, null);
var func42 = (Func<CultureInfo,string>)Delegate.CreateDelegate(typeof(Func<CultureInfo,string>), 42, toStringMethod,true);
Console.WriteLine( object.ReferenceEquals(func37.Method,func42.Method)); //true
Console.WriteLine(func37.Target);//37
Console.WriteLine(func42.Target);//42
Console.WriteLine(func37(CultureInfo.InvariantCulture));//37
Console.WriteLine(func42(CultureInfo.InvariantCulture));//-201040128... WTF?
Calling CreateDelegate
with null
as the target object throws a binding exception if the instance method belonged to a value type (this works for reference types).