AS3: Cast Variable as Dynamic Type

2019-07-17 03:41发布

问题:

Is it possible to cast a variable as a type dynamically, where the type would be a variable of type Class?

Consider the following (invalid):

var myClass:Class = MyClass;
var myInstance:myClass = new myClass();

For context: I'm working in Flex (4) to create a modal manager that will control various aspects of creating modals (via PopUpManager) and I'd like to keep it as minimal as possible. Components would be passed through the same functions, and rather than allowing any type of variable to be cast, eg:

var myInstance:* = new myClass();

I'd rather keep it as explicit as possible. Granted AFAIK there is no -real- advantage to doing this, as there are checks to make sure that the argument is of type Class before assigning - it's more of a POC than anything.

Any thoughts are welcome.

Edit: I suppose I could do the following:

var myClass:Class = MyClass;
var myInstance:* = new myClass() as myClass;

but I'm not sure if that's the best way to go about it.

回答1:

I don't think the compiler can handle dynamic typing. If it could, it would be possible to implement features similar to Generics.

I think the best you can do is:

var myClass:Class = MyClass;
var myObject:* = new myClass();


回答2:

I don't know if this is the same as the problem you are having or not. I needed to have a class that had a child that implemented an interface. The implementing class could be any kind but I needed to save and load all of it's information.

Let's say I have a the following:

public interface WindowChild {...}

and

public class Window {
    public var child:WindowChild;
}

when it came time to save the window I saved everything in an XML blob. I found a function in the Flash player:
flash.utils.getQualifiedClassName(value:*):String
The documentation says: "Returns the fully qualified class name of an object." Which means the String it returns will be something like your.packages::ClassName. When the Window class makes the call getQualifiedClassName(child) it gets something like my.packages.structure::MyImplementation.
Note that this isn't the path to the Interface WindowChild but rather the class I created that implemented that interface.

When it came time to load all that information again I used another Flash function getQualifiedClassName(child). This function "Returns a reference to the class object of the class specified by the name parameter." which I think is just a fancy way of saying that it returns an Object but it will be of type Class.

All I needed to do then was:

var childClass:Class = getDefinitionByName(childClassName) as Class; //Child class name is what was returned from getQualifiedClassName(child)
child = new childClass(); // This creates a new Object of what ever type childClass is

This approach will leave the type checking for run time but you can always add another intermediate step to ensure what is returned from new childClass() is what you want.

Hopefully that was useful.

Cheers



回答3:

I don't think so. When I expect to have more than one type passed in I do something like this:

public function doSomethingWithThis(something:Object):void {
    var button:Button = something as Button;
    var image:Image = something as Image;
    var list:List = something as List;


    if (button) {


    }
    else if (image) {


    }
    else if (list) {


    }
    else {
        throw new Error("This type of object will not work with this method.");
    }


}