Activator.CreateInstance 与 Delegate 参数
Posted
技术标签:
【中文标题】Activator.CreateInstance 与 Delegate 参数【英文标题】:Activator.CreateInstance with Delegate parameter 【发布时间】:2021-09-18 18:58:11 【问题描述】:我想通过反射从第三方程序集创建一个内部类的实例。
类看起来像这样
internal sealed class SomeClass
public delegate object SomeDelegate(object value);
public SomeDelegateHandler get; private set;
public SomeClass(SomeDelegate handler)
this.Handler = handler;
通常我会使用反射来创建内部类的实例,但我需要传递一个SomeDelegate
委托。
由于该委托在内部类中,我也需要通过反射创建该委托的实例。但是我已经尝试过的所有方法都不起作用
这是我迄今为止尝试过的。
// 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);
【问题讨论】:
您知道要在编译时创建的委托类型,还是动态的?目前尚不清楚您的真实背景是什么。但 Delegate.CreateDelegate 可能是你想要的,如果它都是动态的。 我同意乔恩的观点。委托总是引用一个方法(包括匿名方法和 lambdas)。因此,为了创建委托,您需要将引用的方法与您要创建的新委托变量连接起来。在反射MethodInfo.CreateDelegate
或Delegate.CreateDelegate
是要走的路。
@JonSkeet 我知道类型,但它在第三方程序集的内部类中,所以我也需要重新选择。 var t = assembly.GetType("ThirdParty.SomeClass+SomeDelegateHandler ", true, true); var method = this.GetType().GetMethod("SomeDelegateImplementation"); var args = new [] Delegate.CreateDelegate(t, m);
有效。谢谢乔恩,不知道CreateDelegate
。如果您将此作为答案发布,我可以将其标记为已接受。
如果你编辑问题来澄清它,我会这样做,最好是一个完整的例子。这将使它成为对未来访问者更有用的问题。
@JonSkeet 我更新了我的问题以包含更多详细信息和解决方案。
【参考方案1】:
解决方案
感谢@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);
【讨论】:
以上是关于Activator.CreateInstance 与 Delegate 参数的主要内容,如果未能解决你的问题,请参考以下文章
笔记 Activator.CreateInstance(Type)
Activator.CreateInstance(type) 抛出异常
Activator.CreateInstance - 如何创建具有参数化构造函数的类的实例
ProtoBuf-net AsReference 需要 Activator.CreateInstance 中的公共构造函数?