C# 将 DynamicObject 转换为任意类型
我正在写一个 Javascript <-> C# 桥并遇到以下问题:
有一个 JSObject 类:
public class JSObject : DynamicObject
{
public JSEngineAPI wrappedObject { get; set; }
public JSObject(JSEngineAPI WrappedObject);
public override bool TryConvert(ConvertBinder binder, out object result);
public override bool TryGetMember(GetMemberBinder binder, out object result);
...
}
让我们假设有一个简单的测试用例,例如
public class TestClass
{
public string message = "This is a C# string";
}
public class TestApp
{
public string testComplexObject(TestClass obj)
{
return obj.message;
}
}
现在我希望能够执行
JSObject jsObj = ...;
string message = testComplexObject(jsObj);
obj.message
应该执行 TryGetMember( )
调用。实际上,jsObj 应该伪装成一个 TestClass 实例。请注意,对 testComplexObject 的调用只是一个示例,稍后我需要能够支持使用任意参数调用任意函数。
我尝试了各种方法来实现这项工作,但没有一个有效。所以我想知道有什么好方法来实现这一目标。
我考虑过在运行时创建一个继承自 TestClass 的类。该动态类将包含生成的成员,这些成员会重载其基类挂件。这些方法中的每一个都会转发到 JSObject/JSEngineAPI 来执行实际工作。然后我可以将这个动态类的实例传递到 testComplexObject 方法中。
然而,这听起来相当复杂,我很想知道是否有更简单/其他的方法。
编辑#1:我想如果你去掉“DynamicObject”部分,这个问题有点像如何在运行时为类型 T 创建代理?
编辑 #2: 我现在还研究了 RealProxy 和 IDynamicMetaObjectProvider,想知道它们是否有任何帮助。
感谢您抽出时间, ——马蒂亚斯
I'm writing a Javascript <-> C# bridge and ran into the following problem:
There's a class JSObject:
public class JSObject : DynamicObject
{
public JSEngineAPI wrappedObject { get; set; }
public JSObject(JSEngineAPI WrappedObject);
public override bool TryConvert(ConvertBinder binder, out object result);
public override bool TryGetMember(GetMemberBinder binder, out object result);
...
}
and let's assume there's a simple test case like
public class TestClass
{
public string message = "This is a C# string";
}
public class TestApp
{
public string testComplexObject(TestClass obj)
{
return obj.message;
}
}
Now I want to be able to do
JSObject jsObj = ...;
string message = testComplexObject(jsObj);
Doing obj.message
should perform a TryGetMember()
call. Effectively the jsObj should pretend to be a TestClass instance. Note that the call to testComplexObject is just an example, later I need to be able to support calling arbitrary functions with arbitrary arguments.
I've tried various ways to make this work, but none of them worked. So I wonder about a good way to achieve this.
I've thought about creating a class at runtime which inherits from TestClass. This dynamic class will contain generated members which overload their base class pendants. Each of these methods would forward to the JSObject/JSEngineAPI to perform the real work. Then I could pass an instance of this dynamic class into the testComplexObject method.
However this sounds rather involved and I'd love to know if there are easier/other approaches to this.
EDIT #1: I guess if you take away the "DynamicObject" part this question is a bit like how can I create a proxy for type T at runtime?
EDIT #2: I've also looked into RealProxy and IDynamicMetaObjectProvider now and wonder if these are of any help.
Thanks for your time,
-Matthias
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于方法的签名无法更改,因此您可以创建一个代理来代替动态对象。仅当对象是 POD 或您坚持使用可以重写的虚拟方法时,这才有效。否则你的方法可能最终不会被使用。它将实现所需的类型,但会将所有访问传递给您的实际对象。如果您向动态对象添加一些转换方法,那么使用它会很容易。像这样的事情:
如果您需要对对象执行更多操作,除了更改方法的签名之外,我不知道您还能如何解决此问题。
As the signature of the method cannot be changed, you could create a proxy to stand in for your dynamic object. This will be effective only if the objects are PODs or you stick to virtual methods that you could override. Otherwise your methods could end up not being used. It will implement the the desired type but will pass all accesses to your actual object. Using this will be easy if you add some conversion methods to your dynamic object. Something like this:
If you need to do more with your objects, I don't know how else you could get around this other than changing the method's signature.