我有这样的内部方法
void Foo(Action<DB> act)
类DB在同一程序集中,并且也标记为内部。我可以解决如何获取Foo的methodinfo的方法,但是无法解决如何在调用代码中设置回调act
的方法。到目前为止,这就是我所拥有的(作为一种附加的香料,我想从回调内部调用另一个内部方法)
var tt = eng.GetType().Assembly;
var dd = tt.GetType("Internal.DB");
var kk = typeof(Action<>);
Type[] targs = { dd };
var qq = kk.MakeGenericType(targs);
MethodInfo dynMethod = eng.GetType().GetMethod("Foo", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { qq },null);
dynMethod.Invoke(this, new object[] {
((Action<object>)(db=>{
MethodInfo dynMethod2 = db.GetType().GetMethod("Wiz", BindingFlags.NonPublic | BindingFlags.Instance);
dynMethod2.Invoke(db);
})) });
我的问题在这里(我认为)
((Action<object>)(db=>{
我真的需要
((Action<DB>)(db=>{
但是我不能这样做(DB是内部的),带有object
的那个可以编译,但是在运行时失败,说明该对象的类型错误。
答案 0 :(得分:0)
我对您的示例所做的更改很少,并且得到了可以编译并运行完成的代码。您的DB.Wiz()是否有可能引发异常?如果不是这样,我们可能需要更多有关哪个运行时给您这个问题的信息,或者提供更完整的示例。下面的示例正确输出"Hello, World!"
.Net 4.6.1解决方案
ConsoleApp项目,已引用类库名称空间Internal
。我将您的dynMethod2.Invoke()
更改为传递一个空对象[],因为您的示例未使用一个参数编译到Invoke
。还删除了lambda表达式周围的多余括号。
private static void Main(string[] args)
{
Internal.Eng eng = new Internal.Eng();
var tt = eng.GetType().Assembly;
var dd = tt.GetType("Internal.DB");
var kk = typeof(Action<>);
Type[] targs = { dd };
var qq = kk.MakeGenericType(targs);
MethodInfo dynMethod = eng.GetType().GetMethod("Foo", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { qq }, null);
dynMethod.Invoke(eng, new object[] {
(Action<object>)(db=>{
MethodInfo dynMethod2 = db.GetType().GetMethod("Wiz", BindingFlags.NonPublic | BindingFlags.Instance);
dynMethod2.Invoke(db, new object[]{ });
})
});
}
类库Internal
命名空间。
using System;
namespace Internal
{
public class Eng
{
internal void Foo(Action<DB> act) => act(new DB());
}
internal class DB
{
internal void Wiz()
{
Console.WriteLine("Hello, World!");
}
}
}
答案 1 :(得分:0)
很难确切地知道您要执行的操作,但是如果Wiz是不接受任何参数的DB方法,那么我相信您会遵循以下要求:
dynMethod.Invoke(this, new object[] {
((Action<DB>)(db=> {
MethodInfo dynMethod2 = db.GetType().GetMethod("Wiz", BindingFlags.NonPublic | BindingFlags.Instance);
dynMethod2.Invoke(db, null);
})) });