ActionScript 3 で Vector クラスの配列を動的に生成するには
オブジェクトのシリアライズに関する実装をする上で、Vector クラスのリフレクションはできるのか調べてみた。
Vectorクラス名を取得
var classInfo:Object = ObjectUtil.getClassInfo(Vector.<Entity>); trace(classInfo.name);
とすると出力は下記のようになった。
__AS3__.vec::Vector.<com.tilfin.sample::Entity>
こんどは、getDefinitionByName を使って生成してみると
var cls:Class = getDefinitionByName("__AS3__.vec::Vector.<com.tilfin.sample::Entity>") as Class var vector:Vector.<Entity> = new cls();
もちゃんと上手くいった。ということで色々できそうです。
Vectorユーティリティクラス
サンプルとして試しに書いてみた。
package { import flash.utils.getDefinitionByName; import flash.utils.getQualifiedClassName; public class VectorUtil { /** * 指定されたオブジェクトをエレメントとするVectorクラスの配列を返します。 * * @param args 1つ以上のオブジェクトもしくは配列 * @return Vectorインスタンス * */ public static function toVector(...args):* { var item:*; var items:Array; if (args.length == 1) { item = args[0]; if (item is Array) { items = item as Array; } else { items = [ item ]; } } else { items = args as Array; } if (!items || items.length == 0) { throw new ArgumentError("requires at least one argument."); } item = items.shift(); var vectorClass:Class = getVectorClass(item); var vector:* = new vectorClass(); vector.push(item); for each (var i:* in items) { vector.push(i); } return vector; } /** * 指定されたオブジェクトクラスを格納するVectorクラスオブジェクトを返します。 * * @param value 完全修飾クラス名が必要なオブジェクト * @return Vectorクラスオブジェクト * */ public static function getVectorClass(value:*):Class { var className:String; if (value is String) { className = value; } else { className = getQualifiedClassName(value); } return getDefinitionByName("__AS3__.vec::Vector.<" + className + ">") as Class; } } }
下記のエンティティクラスを使って例を実行してみた。
package com.tilfin.sample { public class Entity { private var _name:String; public function Entity(name:String) { _name = name; } public function get name():String { return _name; } } }
import com.tilfin.sample.Entity; private function sample():void { var et1:Entity = new Entity("sample1"); var et2:Entity = new Entity("sample2"); var vector:Vector.<Entity> = VectorUtil.toVector(et1, et2); for each (var item:Entity in vector) { trace(item.name); } }
こんなかんじに書くと、下記のように出力される。
sample1 sample2
なお、Vector クラスは Flash Player 10 もしくは AIR 1.5 以降が必須です。