Reputation: 29331
I'm playing around with Delegates, but I'm clearly not grasping something basic.
I've got the following:
class Test
{
delegate bool Foo();
public void Run()
{
Delegate foo = new Foo((delegate () { return true; }));
bool result = (bool)foo.Method.Invoke(foo, null);
}
}
Test test = new Test();
test.Run();
In the above example I encounter an exception: "Object does not match target type."
The following works alright, though:
class Test
{
delegate bool Foo();
public void Run()
{
Foo foo = new Foo((delegate () { return true; }));
bool result = foo.Invoke();
}
}
Test test = new Test();
test.Run();
What's incorrect with my first implementation? Shouldn't I be invoking foo's method, as foo, with no parameters? This would seem equivalent to the latter code.
Upvotes: 0
Views: 469
Reputation: 63772
You're bypassing the entire reason you'd use the delegate in the first place. As a rule of thumb, don't touch Method
.
The first argument in MethodInfo.Invoke
is the this
instance. This can be null
or something else (e.g. a closure, or the actual object instance when the delegate represents an instance method), but it will never be the delegate instance - that doesn't make any sense.
In your case, it is indeed a closure instance. But you have no reference to the closure outside of the delegate - it's created behind the scene by the compiler. So the only proper way to do the invocation (using MethodInfo
) would be foo.Method.Invoke(foo.Target, null);
. Of course, this is entirely redundant - just use foo();
like any sane human, and you'll be fine :)
The same way, stop using the old delegate syntax. There's little point in doing so. A simple
Func<bool> foo = () => true;
Console.WriteLine(foo());
will work fine. You can substitute your own delegate for Func<bool>
if you really need to, but using custom delegates isn't very useful nowadays.
Upvotes: 3