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;
}
}
} 4 1718
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()) ;
}
}
//...
}
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; } } }
Unless of course, the reference type overloaded the equality operator.
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: domeceo |
last post by:
can anyone tell me why I cannot pass values in a setTimeout function
whenever I use this function it says "menu is undefined" after th
alert.
function imgOff(menu, num) {
if (document.images) {...
|
by: nikola |
last post by:
Hi all,
I was working with a simple function template to find the min of two values.
But since I would like the two values to be different (type) I dont know
what kind of value (type) it will...
|
by: _andrea.l |
last post by:
I'd like to roder an array:
$array
$array
$array
I'd like to order $array by name or by numbre of by a
function($array,$array) that return 1 or -1 if id1 is less tha
id2 or viceversa...
How...
|
by: Ben |
last post by:
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...
|
by: Telmo Costa |
last post by:
Hi. I have the following code:
--------------------------------------
function Tunnel() {
//arguments(???);
}
function Sum() {
var sum = 0;
for (i=0; i<arguments.length; i++) sum +=...
|
by: Larax |
last post by:
Best explanation of my question will be an example, look below at this
simple function:
function SetEventHandler(element)
{
// some operations on element
element.onclick =
function(event)
{
|
by: Daz |
last post by:
Hi everyone.
My query is very straight forward (I think).
What's the difference between
someFunc.blah = function(){ ; }
and
|
by: tnowles00 |
last post by:
Hi friend,
what is the use of function pointer in c language and where it is
useful?
tell with simple example...?
plz help me.
|
by: Julienne Walker |
last post by:
Ignoring implementation details and strictly following the C99
standard in terms of semantics, is there anything fundamentally flawed
with describing the use of a (non-inline) function as an...
|
by: DolphinDB |
last post by:
Tired of spending countless mintues downsampling your data? Look no further!
In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: Vimpel783 |
last post by:
Hello!
Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
|
by: jfyes |
last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
|
by: ArrayDB |
last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
|
by: CloudSolutions |
last post by:
Introduction:
For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
|
by: Defcon1945 |
last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
|
by: Shællîpôpï 09 |
last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
| |