gpt4 book ai didi

c# - 使用 ImpromptuInterface 调用基类的私有(private)成员

转载 作者:行者123 更新时间:2023-11-30 12:31:15 24 4
gpt4 key购买 nike

我有一个框架,允许我使用键盘访问项目中对象的状态和方法。它严重依赖 ImpromptuInterface ,它很棒、快速、灵活等等。

例如,我使用 Impromptu.InvokeMember(myObject, methodName, castParameters) 调用方法。它适用于公共(public)和私有(private)成员,但是当我尝试调用 myObject 基类的私有(private)成员时,我得到 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'MyType.MyMethod(Something) ' 由于其保护级别而无法访问

揭示问题的最简单代码:

public class MainClass
{
public static void Main(string[] args)
{
var type = new PublicType();
var other = new OtherType();
Console.WriteLine(Impromptu.InvokeMember(other, "Method", 2)); //works
Console.WriteLine(Impromptu.InvokeMember(type, "Method", 2)); //crash
}
}

public class PublicType : OtherType
{}

public class OtherType
{
private bool Method(object a)
{
return a != null;
}
}

我理解为什么会出现这样的问题,并且我可以看到一些可能的解决方案,比如寻找定义方法的类并尝试将我的对象转换为该类,但这很重要麻烦。

是否有任何简单的解决方案,最好严格基于 Impromptu?

最佳答案

因此它与 DLR 一起工作的方式是您为调用提供上下文 Type 以便它可以确定哪些方法是可访问的。默认情况下,impromptu 使用您正在调用的对象的类型,因此它通常适用于大多数私有(private)方法,但显然不适用于基类。

在您的情况下,您需要为即兴创建自己的上下文,文档中提到了这一点 UsagePrivate ,它适用于后期绑定(bind)类型以及接口(interface)。文档中也不清楚,但确实如此,您可以为上下文传入一个 typeof() 对象。所以在你的例子中你可以这样做:

var context = InvokeContext.CreateContext;

Console.WriteLine(Impromptu.InvokeMember(context(type, typeof(OtherType)), "Method", 2));

如果您必须对一般情况执行此操作,它并不漂亮,但您始终可以捕获异常并递归地尝试基本类型,对于它第一次工作的一般情况,不应该放慢速度,并且类层次结构通常不是很深,并且由于您只是以交互方式执行一次而不是数千次,所以应该没问题。

var context = InvokeContext.CreateContext;
var type = target.GetType()
while(true){
try{
Console.WriteLine(Impromptu.InvokeMember(context(target, type), "Method", 2));
break;
}catch(RuntimeBinderException ex){
type = type.BaseType;
if(type ==null)
throw ex;
}
}

关于c# - 使用 ImpromptuInterface 调用基类的私有(private)成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14069840/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com