3

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 も調べましたが、これらが役立つかどうか疑問に思っています。

お時間をいただきありがとうございます - マティアス

4

1 に答える 1

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...
}

オブジェクトをさらに処理する必要がある場合は、メソッドのシグネチャを変更する以外にこれを回避する方法がわかりません。

于 2011-03-28T23:40:07.347 に答える