Create delegate via reflection

2019-02-22 07:22发布

问题:

Given an assembly that contains

namespace Foo{public class Bar;}

How could I create an Action<Foo.Bar> from another assembly without referencing the first assembly at compile time?

回答1:

If you use

Type barType = Type.GetType("Foo.Bar, whateverassembly");
Type actionType = typeof(Action<>).MakeGenericType(barType);

actionType will now represent Action<Foo.Bar>. However, to use it, you'll need to contintue to use reflection, so you'll need to find a MethodInfo that fits the signature void(Foo.Bar), and call Delegate.CreateDelegate to create a delegate. And you'll need Delegate.DynamicInvoke to execute it.

Delegate call = Delegate.CreateDelegate(actionType, ...);
...
call.DynamicInvoke(someBar);

Something tells me that's not what you're thinking of...



回答2:

You can't call it Action<Foo.Bar> in your calling code, since you won't have access to that type definition if you don't reference it at compile time. Since Delegates are contravariant, you can return an Action<Object> and use that, or use Action<IBar> where the IBar interface is defined in a referenced assembly, and implemented by Foo.Bar.

If you do return an Action<Object>, you'd either have to use Foo.Bar members via reflection (or dynamic if using C# 4.0) or use cast it to Foo.Bar where the casting code has a reference to the assembly where Foo.Bar is defined.