ObjectInstance inheritance

Sep 25, 2011 at 4:39 AM

I have a problem trying to use the following model (I've omitted the constructors for simplicity):

I then set a ClsB object on the Global object (using SetGlobalValue on the engine), and try to call "objB.a();", but it doesn't work. How can I fix this?

class ClsA : ObjectInstance
{
    [JsFunction(Name = 'a')]
    public void A() {
        Console.WriteLine('a');
    }
}

class ClsB : ClsA
{ }

Coordinator
Sep 25, 2011 at 1:19 PM
Edited Sep 25, 2011 at 1:22 PM

Inheritance doesn't work as you might expect because it is expected that you are using javascript prototypical inheritance, not .NET inheritance.  For this reason, PopulateFunctions only exposes the methods on the most-derived type.

As a workaround, try this:

private class CustomObjectInstance : ObjectInstance
{
    public CustomObjectInstance(ScriptEngine engine)
        : base(engine)
    {
        this.PopulateFunctions();
    }

    protected CustomObjectInstance(ObjectInstance prototype)
        : base(prototype)
    {
    }

    [JSFunction(Name = "a")]
    public int Test1()
    {
        return 5;
    }
}

private class InheritedObjectInstance : CustomObjectInstance
{
    public InheritedObjectInstance(ScriptEngine engine)
        : base(new CustomObjectInstance(engine))
    {
        this.PopulateFunctions();
    }

    [JSFunction(Name = "b")]
    public int Test2()
    {
        return 6;
    }
}

This works by setting the prototype of the derived instance to be an instance of the base class.

Coordinator
Sep 25, 2011 at 1:20 PM

By the way, if you don't want anyone to instantiate your base class, you can make both constructors protected.

Sep 25, 2011 at 1:35 PM

Yes, however, that will not work in my case. Or, it might, but not if I understand it correctly. Because, in this example, when you run in the javascript "yourobject.a()", what object is that run on? The InheritedObjectInstance or the CustomObjectInstance?

Coordinator
Sep 25, 2011 at 9:38 PM

It would run on the CustomObjectInstance of course... hmm, I see your problem.  How about making the method virtual and then overriding it in the base class?

class ClsA : ObjectInstance
{
    [JsFunction(Name = 'a')]
    public virtual void A() {
        Console.WriteLine('a');
    }
}

class ClsB : ClsA
{
    [JsFunction(Name = 'a')]
    public override void A() {
        base.A();
    }
}
Sep 26, 2011 at 12:05 AM

I actually managed to hack myself a solution xD (without doing the hierarchy thingy), and I'll see how it comes to bite me in the but at a later point.

Implement Background-Worker using Jurassic; Check. xD