Activator.CreateInstance 带有委托参数
Activator.CreateInstance with Delegate parameter
我想通过反射从第三方程序集创建内部 class 的实例。
class 看起来像这样
internal sealed class SomeClass
{
public delegate object SomeDelegate(object value);
public SomeDelegateHandler { get; private set; }
public SomeClass(SomeDelegate handler)
{
this.Handler = handler;
}
}
通常我会使用反射来创建内部 class 的实例,但我需要传递一个 SomeDelegate
委托。
由于该委托在内部 class 我也需要通过反射创建该委托的实例。但是我已经尝试过的一切都没有用
这是我目前尝试过的方法。
// This is the method that I need to pass as an argument
public static object SomeDelegateImplementation(object value)
{
return value;
}
public void Main()
{
// example: create SomeClass without reflection
// (this is how SomeClass is usually constructed);
var instance = new SomeClass(SomeDelegateImplementation);
// setup: get the ConstructorInfo so I can use
// ctor.Invoke(...) to create an instance of that class
var assembly = typeof(ThirdParty.OtherClass).Assembly;
var type = assembly.GetType("ThirdParty.SomeClass", true, true);
var ctor = type.GetConstructors()[0];
// method one (doesn't work)
// compiler error: cannot convert method group 'SomeDelegateImplementation' to non-delegate type 'object'. Did you intend to invoke the method?
var args = new object[]{ SomeDelegateImplementation };
var instance = ctor.Invoke(args);
// method two (doen't work)
// throws a runtime error during invoke:
// error converting object with type "System.Func`2[System.Object,System.Object]" to type "ThirdParty.SomeClass+SomeDelegate".
Func<object, object> someDelegateImplementation = SomeDelegateImplementation;
var args = new object[]{ (Delegate)someDelegateImplementation };
var instance = ctor.Invoke(args);
}
解决方案
感谢@JonSkeet,我设法使用 Delegate.CreateDelegate
创建了 SomeClass
的实例
Assembly assembly = typeof(ThirdParty.OtherClass).Assembly;
Type type = assembly.GetType("ThirdParty.SomeClass", true, true);
ConstructorInfo ctor = type.GetConstructors()[0];
// get a reference to the original delegate type
Type someDelegateHandler Type =
assembly.GetType("ThirdParty.SomeClass+SomeDelegateHandler", true, true);
// get a reference to my method
MethodInfo someDelegateImplementationMethod =
typeof(Program).GetMethod("SomeDelegateImplementation",
BindingFlags.Static | BindingFlags.NonPublic);
// create a delegate that points to my method
Delegate someDelegateImplementationDelegate =
Delegate.CreateDelegate(
someDelegateHandler, someDelegateImplementationMethod);
object[] args = new object[]{ someDelegateImplementationDelegate };
object instance = ctor.Invoke(args);
我想通过反射从第三方程序集创建内部 class 的实例。
class 看起来像这样
internal sealed class SomeClass
{
public delegate object SomeDelegate(object value);
public SomeDelegateHandler { get; private set; }
public SomeClass(SomeDelegate handler)
{
this.Handler = handler;
}
}
通常我会使用反射来创建内部 class 的实例,但我需要传递一个 SomeDelegate
委托。
由于该委托在内部 class 我也需要通过反射创建该委托的实例。但是我已经尝试过的一切都没有用
这是我目前尝试过的方法。
// This is the method that I need to pass as an argument
public static object SomeDelegateImplementation(object value)
{
return value;
}
public void Main()
{
// example: create SomeClass without reflection
// (this is how SomeClass is usually constructed);
var instance = new SomeClass(SomeDelegateImplementation);
// setup: get the ConstructorInfo so I can use
// ctor.Invoke(...) to create an instance of that class
var assembly = typeof(ThirdParty.OtherClass).Assembly;
var type = assembly.GetType("ThirdParty.SomeClass", true, true);
var ctor = type.GetConstructors()[0];
// method one (doesn't work)
// compiler error: cannot convert method group 'SomeDelegateImplementation' to non-delegate type 'object'. Did you intend to invoke the method?
var args = new object[]{ SomeDelegateImplementation };
var instance = ctor.Invoke(args);
// method two (doen't work)
// throws a runtime error during invoke:
// error converting object with type "System.Func`2[System.Object,System.Object]" to type "ThirdParty.SomeClass+SomeDelegate".
Func<object, object> someDelegateImplementation = SomeDelegateImplementation;
var args = new object[]{ (Delegate)someDelegateImplementation };
var instance = ctor.Invoke(args);
}
解决方案
感谢@JonSkeet,我设法使用 Delegate.CreateDelegate
SomeClass
的实例
Assembly assembly = typeof(ThirdParty.OtherClass).Assembly;
Type type = assembly.GetType("ThirdParty.SomeClass", true, true);
ConstructorInfo ctor = type.GetConstructors()[0];
// get a reference to the original delegate type
Type someDelegateHandler Type =
assembly.GetType("ThirdParty.SomeClass+SomeDelegateHandler", true, true);
// get a reference to my method
MethodInfo someDelegateImplementationMethod =
typeof(Program).GetMethod("SomeDelegateImplementation",
BindingFlags.Static | BindingFlags.NonPublic);
// create a delegate that points to my method
Delegate someDelegateImplementationDelegate =
Delegate.CreateDelegate(
someDelegateHandler, someDelegateImplementationMethod);
object[] args = new object[]{ someDelegateImplementationDelegate };
object instance = ctor.Invoke(args);