By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
460,023 Members | 1,297 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 460,023 IT Pros & Developers. It's quick & easy.

A Function That Compares the Properties of Two Objects

P: n/a
Hi There

I am learning about reflection so apologies if this post is vague ...

I am doing some unit testing and have written a function that accepts
two objects and tests to see if their properties are equal. It seems
to work OK except when a object has a property that is an array.

The GetValue method of the PropertyInfo class returns an object, and I
want to convert it to an array of objects. For some reason, this
fails:

object[] objectArray = (object[])myObject;

However if I know the type, then it works. For example:

SecurityRoles[] rolesArray = (SecurityRoles[])object;

The problem is that I don't know the type at design time ! I tried to
do this:

propInfo.PropertyType[] objectArray =
(propInfo.PropertyType[])myObject;

But it did not compile (ps ... propInfo is an instance of the
PropertyInfo class).

The code listing for my function is below. I would really appreciate
any guidance!

Thanks
Bill

using System;
using System.Reflection;

namespace ServerTest
{
public static class ObjectComparer
{
/// <summary>
/// This function compares any two objects properties. It will
recursively search down through nested properties
/// WARNING - It only compares properties that are one of the
following string, char, short, int, long, bool, DateTime, Enum
/// *** IT IGNORES ANY PROPERTIES THAT ARE ARRAYS ***
/// </summary>
/// <param name="thisType">The type of the two objects</param>
/// <param name="leftObject"></param>
/// <param name="rightObject"></param>
/// <returns>True to indicate that the objects are equal.
False otherwise</returns>
public static bool AreTheseObjectEqual(Type thisType, object
leftObject, object rightObject)
{
if (leftObject == null && rightObject == null)
return true;

if (leftObject == null || rightObject == null)
return false;

PropertyInfo[] fields = thisType.GetProperties();

foreach (PropertyInfo propInfo in fields)
{
if (propInfo.PropertyType.IsArray)
{
//************************************************** *******************************
//Property is an array, need to iterate through the
elements and compare them

//************************************************** *******************************

//object lhs = propInfo.GetValue(leftObject, null);
//object rhs = propInfo.GetValue(rightObject,
null);

////This does not work
//object[] lhsArray = (object[])lhs;
//object[] rhsArray = (object[])rhs;

////If the above worked, I could then do this:
//if (lhsArray.Length != rhsArray.Length)
// return false;
//else
//{
// for (int i = 0; i < lhsArray.Length; i++)
// {
// if (false ==
AreTheseObjectEqual(propInfo.PropertyType,
(object)lhsArray[i],(object)rhsArray[i]))
// return false;
// }
//}

//BUT .... If I knew the type then this would
work:
//STE.Model.SecurityRoles[] secRolesLHS =
(STE.Model.SecurityRoles[])lhs;
//STE.Model.SecurityRoles[] secRolesRHS =
(STE.Model.SecurityRoles[])rhs;
//But I don't know the type at run time
}
else
{
object lhs = propInfo.GetValue(leftObject, null);
object rhs = propInfo.GetValue(rightObject, null);

if (propInfo.PropertyType.IsEnum)
{
if (lhs.ToString() != rhs.ToString())
return false;
}
else if (lhs is string)
{
if (false == rhs is string)
return false;
if ((string)lhs != (string)rhs)
return false;
}
else if (lhs is char)
{
if (false == rhs is char)
return false;
if ((char)lhs != (char)rhs)
return false;
}
else if (lhs is bool)
{
if (false == rhs is bool)
return false;
if ((bool)lhs != (bool)rhs)
return false;
}
else if (lhs is short)
{
if (false == rhs is short)
return false;
if ((long)lhs != (long)rhs)
return false;
}
else if (lhs is int)
{
if (false == rhs is int)
return false;
if ((int)lhs != (int)rhs)
return false;
}
else if (lhs is long)
{
if (false == rhs is long)
return false;
if ((long)lhs != (long)rhs)
return false;
}
else if (lhs is DateTime)
{
if (false == rhs is DateTime)
return false;
if ((DateTime)lhs != (DateTime)rhs)
return false;
}
else
{
PropertyInfo[] nestedFields =
propInfo.PropertyType.GetProperties();
if (nestedFields.Length > 0)
{
if (false ==
AreTheseObjectEqual(propInfo.PropertyType,
propInfo.GetValue(leftObject, null), propInfo.GetValue(rightObject,
null)))
return false;
}
}
}
}
return true;
}
}
}

Nov 17 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Thats not so hard to do:

//...

PropertyInfo[] fields = thisType.GetProperties();
foreach (PropertyInfo propInfo in fields) {

if (propInfo.PropertyType.IsArray) {
object val = propInfo.GetValue(angel, null);

IEnumerator ie = ((System.Array)val).GetEnumerator();
while(ie.MoveNext()) {
//Now we have the individual object in the array
Console.WriteLine(ie.Current.GetType().ToString()) ;
}
}

//...
}

Nov 17 '05 #2

P: n/a
Hi,
Ashura's post should solve your problem, I just want to remember you that if
a property has a reference type you are comparing references ( if both
instances refers to the very same instance, not two instances with same
values).
cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

<or*******@yahoo.com.au> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...
Hi There

I am learning about reflection so apologies if this post is vague ...

I am doing some unit testing and have written a function that accepts
two objects and tests to see if their properties are equal. It seems
to work OK except when a object has a property that is an array.

The GetValue method of the PropertyInfo class returns an object, and I
want to convert it to an array of objects. For some reason, this
fails:

object[] objectArray = (object[])myObject;

However if I know the type, then it works. For example:

SecurityRoles[] rolesArray = (SecurityRoles[])object;

The problem is that I don't know the type at design time ! I tried to
do this:

propInfo.PropertyType[] objectArray =
(propInfo.PropertyType[])myObject;

But it did not compile (ps ... propInfo is an instance of the
PropertyInfo class).

The code listing for my function is below. I would really appreciate
any guidance!

Thanks
Bill

using System;
using System.Reflection;

namespace ServerTest
{
public static class ObjectComparer
{
/// <summary>
/// This function compares any two objects properties. It will
recursively search down through nested properties
/// WARNING - It only compares properties that are one of the
following string, char, short, int, long, bool, DateTime, Enum
/// *** IT IGNORES ANY PROPERTIES THAT ARE ARRAYS ***
/// </summary>
/// <param name="thisType">The type of the two objects</param>
/// <param name="leftObject"></param>
/// <param name="rightObject"></param>
/// <returns>True to indicate that the objects are equal.
False otherwise</returns>
public static bool AreTheseObjectEqual(Type thisType, object
leftObject, object rightObject)
{
if (leftObject == null && rightObject == null)
return true;

if (leftObject == null || rightObject == null)
return false;

PropertyInfo[] fields = thisType.GetProperties();

foreach (PropertyInfo propInfo in fields)
{
if (propInfo.PropertyType.IsArray)
{
//************************************************** *******************************
//Property is an array, need to iterate through the
elements and compare them

//************************************************** *******************************

//object lhs = propInfo.GetValue(leftObject, null);
//object rhs = propInfo.GetValue(rightObject,
null);

////This does not work
//object[] lhsArray = (object[])lhs;
//object[] rhsArray = (object[])rhs;

////If the above worked, I could then do this:
//if (lhsArray.Length != rhsArray.Length)
// return false;
//else
//{
// for (int i = 0; i < lhsArray.Length; i++)
// {
// if (false ==
AreTheseObjectEqual(propInfo.PropertyType,
(object)lhsArray[i],(object)rhsArray[i]))
// return false;
// }
//}

//BUT .... If I knew the type then this would
work:
//STE.Model.SecurityRoles[] secRolesLHS =
(STE.Model.SecurityRoles[])lhs;
//STE.Model.SecurityRoles[] secRolesRHS =
(STE.Model.SecurityRoles[])rhs;
//But I don't know the type at run time
}
else
{
object lhs = propInfo.GetValue(leftObject, null);
object rhs = propInfo.GetValue(rightObject, null);

if (propInfo.PropertyType.IsEnum)
{
if (lhs.ToString() != rhs.ToString())
return false;
}
else if (lhs is string)
{
if (false == rhs is string)
return false;
if ((string)lhs != (string)rhs)
return false;
}
else if (lhs is char)
{
if (false == rhs is char)
return false;
if ((char)lhs != (char)rhs)
return false;
}
else if (lhs is bool)
{
if (false == rhs is bool)
return false;
if ((bool)lhs != (bool)rhs)
return false;
}
else if (lhs is short)
{
if (false == rhs is short)
return false;
if ((long)lhs != (long)rhs)
return false;
}
else if (lhs is int)
{
if (false == rhs is int)
return false;
if ((int)lhs != (int)rhs)
return false;
}
else if (lhs is long)
{
if (false == rhs is long)
return false;
if ((long)lhs != (long)rhs)
return false;
}
else if (lhs is DateTime)
{
if (false == rhs is DateTime)
return false;
if ((DateTime)lhs != (DateTime)rhs)
return false;
}
else
{
PropertyInfo[] nestedFields =
propInfo.PropertyType.GetProperties();
if (nestedFields.Length > 0)
{
if (false ==
AreTheseObjectEqual(propInfo.PropertyType,
propInfo.GetValue(leftObject, null), propInfo.GetValue(rightObject,
null)))
return false;
}
}
}
}
return true;
}
}
}

Nov 17 '05 #3

P: n/a
Unless of course, the reference type overloaded the equality operator.

Nov 17 '05 #4

P: n/a
Ben
Great !!! It appears to be working perfectly. Thanks everyone for your help.

If you are interested I have posted the complete code:

https://msdn.microsoft.com/newsgroup...5-583e484fb370

It is my first foray into reflection and recursion, so I would be interested
in any feedback

Cheers
Bill
Nov 17 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.