我正在写一个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,并想知道这些是否有任何帮助。
谢谢你的时间, -Matthias
答案 0 :(得分:3)
由于无法更改方法的签名,因此可以创建代理以代替动态对象。仅当对象是POD或您坚持可以覆盖的虚拟方法时,这才有效。否则,您的方法最终可能无法使用。它将实现所需的类型,但会将所有访问权限传递给您的实际对象。如果向动态对象添加一些转换方法,使用它将很容易。像这样:
public class JSObject : DynamicObject
{
class TestClassProxy : TestClass
{
private dynamic wrapper;
public TestClassProxy(dynamic obj)
{
wrapper = obj;
// assign copies of the fields
message = obj.message;
}
// override all required methods and properties
public override void SampleMethod()
{
wrapper.SampleMethod();
}
public override int SomeValue
{
get { return wrapper.SomeValue; }
set { wrapper.SomeValue = value; }
}
// etc...
}
public override bool TryConvert(ConvertBinder binder, out object result)
{
if (binder.Type == typeof(TestClass))
{
result = new TestClassProxy(this);
return true;
}
// your other conversions
return base.TryConvert(binder, out result);
}
// etc...
}
如果你需要对你的对象做更多的事情,我不知道除了改变方法的签名之外你还能解决这个问题。