Question

J'écris un pont JavaScript <-> C # et j'ai rencontré le problème suivant:

Il y a une classe 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);
    ...
}

Et supposons qu'il y a un simple cas de test comme

public class TestClass
{
    public string message = "This is a C# string";
}

public class TestApp
{
    public string testComplexObject(TestClass obj)
    {
        return obj.message;
    }
}

Maintenant je veux pouvoir faire

JSObject jsObj = ...;
string message = testComplexObject(jsObj);

Action obj.message devrait effectuer un TryGetMember() appel. Effectivement, le JSOBJ devrait prétendre être une instance de classe de test. Notez que l'appel à TestComplexObject n'est qu'un exemple, plus tard, je dois être en mesure de prendre en charge l'appel des fonctions arbitraires avec des arguments arbitraires.

J'ai essayé diverses façons de faire ce travail, mais aucun d'entre eux n'a fonctionné. Je me demande donc une bonne façon d'y parvenir.

J'ai pensé à créer une classe lors de l'exécution qui hérite de TestClass. Cette classe dynamique contiendra des membres générés qui surchargeront leurs pendentifs de classe de base. Chacune de ces méthodes transmettrait le JSObject / JSengeneapi pour effectuer le vrai travail. Ensuite, je pouvais passer une instance de cette classe dynamique dans la méthode TestComplexObject.

Cependant, cela semble plutôt impliqué et j'aimerais savoir s'il y a des approches plus faciles / autres à ce sujet.

EDIT # 1: Je suppose que si vous enlevez la partie "dynamicObject", cette question est un peu comme comment puis-je créer un proxy pour le type T lors de l'exécution?

EDIT # 2: J'ai également examiné le realproxy et idynamicmetaObjectProvider maintenant et je me demande si ceux-ci sont d'une aide.

Merci pour votre temps, -mathias

Était-ce utile?

La solution

Comme la signature de la méthode ne peut pas être modifiée, vous pouvez créer un proxy pour représenter votre objet dynamique. Cela ne sera efficace que si les objets sont des gousses ou si vous vous en tenez aux méthodes virtuelles que vous pourriez remplacer. Sinon, vos méthodes pourraient finir par ne pas être utilisées. Il implémentera le type souhaité mais passera tous les accès à votre objet réel. L'utilisation sera facile si vous ajoutez des méthodes de conversion à votre objet dynamique. Quelque chose comme ça:

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

Si vous avez besoin de faire plus avec vos objets, je ne sais pas comment vous pouvez contourner cela autre que de modifier la signature de la méthode.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top