Unless you want a completely generic solution (how many classes are you gonna compare anyway?), write a custom compare
function in the respective class that goes through the class's properties and return a boolean value.
Update:
Thanks dan for the describeType
. One thing to be careful about describeType is that it reflects only the public variables/properties of a class. private/protected/internal stuff is not included in the describeType's output. Hence if you use it to compare two objects that have same public properties but different private properties, it will still tell you that they are equal.
Here is an AS class and its describeType output.
Data.as
package
{
public class Data
{
private var privateVar:Boolean;
protected var protectedVar:Boolean;
internal var internalVar:Boolean;
var noModifierVar:Boolean;
public var publicVar:Boolean;
public function set writeOnlyProp(value:Boolean):void
{
}
public function get readOnlyProp():Boolean
{
return true;
}
public function set readWriteProp(value:Boolean):void
{
}
public function get readWriteProp():Boolean
{
return false;
}
public function Data(pub:Boolean = false, priv:Boolean = false,
prot:Boolean = false, inter:Boolean = false)
{
this.privateVar = priv;
this.protectedVar = prot;
this.internalVar = inter;
this.publicVar = pub;
}
}
}
The output from describeType
: notice that only public variables have been listed here.
<type name="Data" base="Object" isDynamic="false" isFinal="false" isStatic="false">
<extendsClass type="Object"/>
<constructor>
<parameter index="1" type="Boolean" optional="true"/>
<parameter index="2" type="Boolean" optional="true"/>
<parameter index="3" type="Boolean" optional="true"/>
<parameter index="4" type="Boolean" optional="true"/>
</constructor>
<accessor name="readOnlyProp" access="readonly" type="Boolean" declaredBy="Data"/>
<variable name="publicVar" type="Boolean"/>
<accessor name="readWriteProp" access="readwrite" type="Boolean" declaredBy="Data"/>
<accessor name="writeOnlyProp" access="writeonly" type="Boolean" declaredBy="Data"/>
</type>
The generic comparison code would look like:
public static function compareObjects(a:Object, b:Object):Boolean
{
var description:XML = describeType(a);
var bDescription:XML = describeType(b);
//different classes
if(description.toXMLString() != bDescription.toXMLString())
return false;
if(String(description.@isDynamic) == "true")
{
var t:*;
for(t in a)
if(a[t] != b[t])
return false;
//Just in case b has a dynamic property that a doesn't
for(t in b)
if(a[t] != b[t])
return false;
}
var properties:Array = [];
//readonly and readwrite properties
var accessors:XMLList = description.accessor.(@access != "writeonly");
var type:XML;
for each(type in accessors)
properties.push(String(type.@name));
//other variables
var variables:XMLList = description.variable;
for each(type in variables)
properties.push(String(type.@name));
for each(var prop:String in properties)
{
if(a[prop] != b[prop])
return false;
}
return true;
}
PS: After writing all this code I still feel that writing custom code in the respective class is the correct way to go as this doesn't take private/protected data into account.