Say you’re working on some sort of reflection/deserialization system in Flex, Flash, or another ActionScript 3 technology. It would be nice to know the type of all the fields on an object or class, including accessors, so that you can automagically infer the right way to parse your serialization data. You can use describeType to do this but it has some overhead – dumping a full XML description of a complex type can’t be something you’d want to do frequently, and then you have to parse it again.
I present the ClassFieldCache. It contains one static method, getFieldsOfClass, which will return a dictionary of types indexed by field name. It returns every kind of property you can set – both fields and accessors. (And it ignores constants and readonly accessors.)
Usage is like this:
var dict:Dictionary = ClassFieldCache.getFieldsOfClass(myObject);
trace("Field boo is of type " + dict["boo"]);
Which outputs “Field boo is of type flash.geom::Point” – or whatever that field happens to be.
And the class itself is as follows:
import flash.utils.*;
/**
* Utility class to get list of fields on an object or class.
*/
public class ClassFieldCache
{
/// Indexed by Class, this contains dictionaries mapping name to type (string).
private static var smFieldInfoCache:Dictionary = new Dictionary(true);
/**
* Return a dictionary describing every settable field on this object or class.
*
* Fields are indexed by name, and the type is contained as a string.
*/
public static function getFieldsOfClass(c:*):Dictionary
{
if(!(c is Class))
{
// Convert to its class.
c = getDefinitionByName(getQualifiedClassName(c));
}
// Is it cached? If so, return that.
if(smFieldInfoCache.hasOwnProperty(c))
return smFieldInfoCache[c];
// Otherwise describe the type...
var typeXml:XML = describeType(c);
// Set up the dictionary
var typeDict:Dictionary = new Dictionary();
// Walk all the variables...
for each (var variable:XML in typeXml.factory.variable)
typeDict[variable.@name.toString()] = variable.@type.toString();
// And all the accessors...
for each (var accessor:XML in typeXml.factory.accessor)
{
// Ignore ones we can't write to.
if(accessor.@access == "readonly")
continue;
typeDict[accessor.@name.toString()] = accessor.@type.toString();
}
// Don't forget to stuff it in the cache.
smFieldInfoCache[c] = typeDict;
return typeDict;
}
}
Hope this is useful for you. You’re free to use it however you like. Attribution would be appreciated.