Tho*_*hom 6 c# proxy dynamic method-missing c#-4.0
有没有人知道一种方法来拦截dynamic
方法调用(特别是那些将要提升RuntimeBinderException
s的方法)RealProxy
?我希望捕获异常并在其上实现'方法缺失',但它似乎在拦截器获得查看之前被抛出.
我的测试看起来像:
dynamic hello = MethodMissingInterceptor<DynamicObject>.Create();
Assert.AreEqual("World", hello.World());
Run Code Online (Sandbox Code Playgroud)
哪里World
没有实际实施DynamicObject
.拦截器是非常简单的-我希望检查IMethodReturnMessage.Exception
的RuntimeBinderException
,并转发到是这样的:
public IMessage MethodMissing(IMethodCallMessage call)
{
return new ReturnMessage(call.MethodBase.Name, new object[0], 0, call.LogicalCallContext, call);
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我在拦截器中看到的只是一些调用GetType
,而不是不存在的World
方法.
失败了 - 有没有人知道是否有一个DynamicProxy
版本在.NET 4.0上运行得很快但可能解决了这个问题?
Chr*_*ows 17
我将从长篇大论开始.C#中动态操作的每个绑定按此顺序执行大约这三项操作:
您正在看到GetType调用,因为在第2步中,C#运行时绑定器正在反映您,以尝试确定您是否有适合调用的"World"方法,并且这种情况正在发生,因为IDLOMetaObjectProvider实现了hello,如果有的话,无法想出任何特别的事情.
不幸的是,在抛出RuntimeBinderException时,我们不再绑定了.异常来自动态操作的执行阶段,以响应由于步骤3返回的元对象.您唯一有机会捕获它是在实际的调用站点.
如果你想在C#中实现method_missing,那么这个策略对你来说不会有用.你确实有一些选择.
一个简单的选择是在MethodMissingInterceptor中实现IDynamicMetaObjectProvider,并遵循包装对象的IDMOP实现.如果内部IDMOP出现故障,您可以绑定到您想要的任何内容(可能是对存储在拦截器中的method_missing委托的调用).这里的缺点是,这仅适用于已知为动态对象的对象,例如那些以IDMOP开头的对象.这是因为您基本上是在步骤1和2之间插入自己.
我能想到的另一个替代方案是实现IDynamicMetaObjectProvider,并在其中对每个绑定做出积极响应,返回对方法的调用,该方法(a)生成C#编译器首先生成绑定的相同代码,并且( b)捕获RuntimeBinderException以调用method_missing方法.这里的缺点是它会非常复杂 - 你需要生成任意委托类型和使用它们的IL,而不是C#运行时绑定程序集中的公共类型,坦率地说,它不适合公共使用.但至少你会得到针对所有操作的方法.
我确信还有其他一些我没有想过的策略,比如你似乎暗示要使用远程代理.我无法想象它们看起来像什么,我不能说它们是否会成功.
这里问题的关键在于C#4.0没有一种能够预测你想做到这一点的设计.具体来说,你不能轻易地在第2步和第3步之间插入自己.这让我得到简短的回答,很抱歉,C#4.0没有method_missing.