Peekmo
Peekmo

Reputation: 2903

Casting Dynamic to an other class

I would like to know if that's possible to cast a Dynamic to an other class (partially or totally)

For example, this code breaks :

class Test {
    public function new() {}
    public var id: String;
}

class Main {
    public static function main() {
        var x:Dynamic = JsonParser.parse("{\"id\":\"sdfkjsdflk\"}");
        var t:Test = cast(x, Test);
    }
}

with the following message

Class cast error

However, my "Test" class has an "id" field like the dynamic object. (That's an example, my use case is more complexe than that ^^)

So, I don't understand how to get an object from my Dynamic one.

Upvotes: 1

Views: 1287

Answers (3)

stroncium
stroncium

Reputation: 1430

Json.parse returns anonymous structure(implementation platform dependent), typed as Dynamic. There isn't a single chance to cast it to anything but Dynamic, unless Json.parse returns Int, Float or String, which some parsers permit, but which isn't actually permitted by JSON specification.

That is this way because, the operation of casting doesn't check what fields some object have. Operation of casting only checks if the object is an instance of class you are casting to. Obviously, anonymous structure can't be an instance of any class(inside haxe abstractions at least).

However, the right way to perform the thing you seem to be trying to perform is the way stated by @Ben Morris, in his answer.

Upvotes: 1

heyitsbmo
heyitsbmo

Reputation: 1755

This isn't exactly casting a dynamic to a class instance but may accomplish the same thing:

  • create an empty instance of the class with Type.createEmptyInstance
  • set all of the fields from the Dynamic object on the new class instance using Reflect

Example:

import haxe.Json;


class Test {
    public function new() {}
    public var id: String;
}

class Main {
    public static function main() {
        var x:Dynamic = Json.parse("{\"id\":\"sdfkjsdflk\"}");
        var t:Test = Type.createEmptyInstance(Test);
        for (field in Type.getInstanceFields(Test))
            if (Reflect.hasField(x, field))
                Reflect.setProperty(t, field, Reflect.getProperty(x, field));

        trace(t.id);
    }
}

Upvotes: 2

Andrew
Andrew

Reputation: 1292

You could use typedef

typedef Test = {
    public var id: String;
}

class Main {
    public static function main() {
        var t:Test = JsonParser.parse("{\"id\":\"sdfkjsdflk\"}");
    }
}

Upvotes: 2

Related Questions