【发布时间】: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 我更新了我的问题以包含更多详细信息和解决方案。
标签: c# .net reflection delegates