comparing object values

  • Thread starter Thread starter Vikram
  • Start date Start date
V

Vikram

How to compare value of two objects. Is there any generic way by which we can
compare value of each property of the 2 object of same type. Also if the
porperty is of type object then it should also compare value of subsequent
poreties in that obejct property.
Thanks
 
Hello Vikram,

The good way for this is implementing IComparable interface http://msdn2.microsoft.com/en-us/library/system.icomparable(vs.71).aspx

---
WBR,
Michael Nemtsev [.NET/C# MVP] :: blog: http://spaces.live.com/laflour

"The greatest danger for most of us is not that our aim is too high and we
miss it, but that it is too low and we reach it" (c) Michelangelo


V> How to compare value of two objects. Is there any generic way by
V> which we can
V> compare value of each property of the 2 object of same type. Also if
V> the
V> porperty is of type object then it should also compare value of
V> subsequent
V> poreties in that obejct property.
V> Thank
 
Hello Vikram,

it's ok. But it gives no ability to compare your objects for those who gonna
use your classes
btw. inside the IComparable u can use reflection

---
WBR,
Michael Nemtsev [.NET/C# MVP] :: blog: http://spaces.live.com/laflour

"The greatest danger for most of us is not that our aim is too high and we
miss it, but that it is too low and we reach it" (c) Michelangelo


V> Using reflection and check properties value is not right way?
V>
V> "Michael Nemtsev [MVP]" wrote:
V>
Hello Vikram,

The good way for this is implementing IComparable interface
http://msdn2.microsoft.com/en-us/library/system.icomparable(vs.71).as
px

---
WBR,
Michael Nemtsev [.NET/C# MVP] :: blog:
http://spaces.live.com/laflour
"The greatest danger for most of us is not that our aim is too high
and we miss it, but that it is too low and we reach it" (c)
Michelangelo

V> How to compare value of two objects. Is there any generic way by
V> which we can
V> compare value of each property of the 2 object of same type. Also
if
V> the
V> porperty is of type object then it should also compare value of
V> subsequent
V> poreties in that obejct property.
V> Thanks
 
For implemeting IComparable, we have to right comparision logic for all the
classes and subcalsses, right? That means we have to check each value type
property's value and then return comparison result. If we go with reflection,
we can have a generic method which will loop through each value type property
and return the result. Hence adding new classes and property will not require
any additional effor?
Please suggest.

Michael Nemtsev said:
Hello Vikram,

it's ok. But it gives no ability to compare your objects for those who gonna
use your classes
btw. inside the IComparable u can use reflection

---
WBR,
Michael Nemtsev [.NET/C# MVP] :: blog: http://spaces.live.com/laflour

"The greatest danger for most of us is not that our aim is too high and we
miss it, but that it is too low and we reach it" (c) Michelangelo


V> Using reflection and check properties value is not right way?
V>
V> "Michael Nemtsev [MVP]" wrote:
V>
Hello Vikram,

The good way for this is implementing IComparable interface
http://msdn2.microsoft.com/en-us/library/system.icomparable(vs.71).as
px

---
WBR,
Michael Nemtsev [.NET/C# MVP] :: blog:
http://spaces.live.com/laflour
"The greatest danger for most of us is not that our aim is too high
and we miss it, but that it is too low and we reach it" (c)
Michelangelo

V> How to compare value of two objects. Is there any generic way by
V> which we can
V> compare value of each property of the 2 object of same type. Also
if
V> the
V> porperty is of type object then it should also compare value of
V> subsequent
V> poreties in that obejct property.
V> Thanks
 
For implemeting IComparable, we have to right comparision logic for all
the
classes and subcalsses, right? That means we have to check each value
type
property's value and then return comparison result. If we go with
reflection,
we can have a generic method which will loop through each value type
property
and return the result. Hence adding new classes and property will not
require
any additional effor?

That's all true. But using reflection will not necessarily always produce
the correct results either.

If you can guarantee that all fields and/or properties that you're
accessing via reflection should be part of the comparison, and you can
guarantee that reflection will access those fields and/or properties in
exactly the order needed for a correct comparison, and the performance
overhead of reflection isn't going to be a problem...if all of those
things are true, then I suppose you can use reflection.

However, those are rarely all going to be true. For most classes that
have a need to be comparable, they contain some members that should
participate in comparisons and some members that should not. They also
have a very specific order in which those members should be compared. And
of course, a common scenario for needing a comparison is for sorting, and
if you're sorting a lot of objects, the last thing you want is a slow
comparison.

As Michael says, you _could_ use reflection to implement IComparable but
that doesn't really avoid any of the problems mentioned above. It's
better in the sense that at least you provide a standard comparison
interface by doing so, but otherwise it's just as bad as using reflection
with a non-standard comparison interface.

Unless you really really have to use reflection, you should be
implementing IComparable, and doing it without reflection. Yes, each
subclass will need to provide their own additional logic for IComparable,
but really...that's not all that hard. Each unless a subclass needs to
insert one of its own data members in the middle of the order of
comparison for the parent class, all they need to do is do the parent's
comparison and then include their own for their added data members, if any.

The effort to do that should be minimal, and it will produce much better
performing, much more maintainable results.

Pete
 
Hi Peter,
Yes u r right. But in my case, Two objects 2 be compared are excatly the
same, and when any property is changed in the original object, I need to
identify that object is changed and have to raise some event. And comparision
is only for 2 object and once or twice for the application.
Please suggest whether reflection will work in this case?
 
Hi Peter,
Yes u r right. But in my case, Two objects 2 be compared are excatly the
same, and when any property is changed in the original object, I need to
identify that object is changed and have to raise some event. And
comparision
is only for 2 object and once or twice for the application.
Please suggest whether reflection will work in this case?

Reflection will always work. The only question is whether it's really the
best way to do something. IMHO, it should be the last resort, used only
when there's no other way to accomplish something. I don't feel that it's
a good general-purpose tool.

It's not really clear to me exactly what you're doing. But some things to
consider: the usual mechanism for detecting property value changes is to
include some code in the property setter that raises an event when the
setter is called. The standard pattern is, if you have a property named
"Foo", then the event would be named "FooChanged".

It sounds as though you expect to check the entire object periodically,
comparing it to another object and if it tests unequal, raising an event.
Even without reflection, that's wasteful since you wind up doing that
comparison regularly, when most of the time it doesn't test unequal (which
is the condition you care about). With reflection it's even worse,
because reflection is a relatively slow way to compare two object
instances.

The other thing is that when you wrote "comparing", Michael and I both
made the assumption that you're trying to do an ordinal comparison. From
your most recent post, it seems that you simply care about equality. So,
while I still recommend doing the comparison without reflection, it
probably makes more sense to override the Object.Equals() method rather
than implementing IComparable.

Of course, I think the best way is to forget this whole comparison stuff
altogether and just raise the event from the property setters.

So, to sum up, here's the ranking of possibly implementations, from best
to worst:

1) raise the event from the property setters
2) poll the objects, overriding and using Object.Equals() to test for
equality
3) poll the obejcts, using reflection to traverse the class members,
comparing each one by one

As you can see, your proposed solution is the worst one. You can use it
if you want, and it will probably work. But there are better choices you
could make.

Pete
 
Thanks peter,
As per ur recommendation, I m thinking of going with approach 2. But is
there any way, by which I can force developer to implement Object.Equal for
any new property added later on. I mean, if later any new property is added,
of some user defined class type r of type string, then developer has to make
sure that he implemented equals for the new class or modify equals method for
any new property?
 
Thanks peter,
As per ur recommendation, I m thinking of going with approach 2. But is
there any way, by which I can force developer to implement Object.Equal
for
any new property added later on. I mean, if later any new property is
added,
of some user defined class type r of type string, then developer has to
make
sure that he implemented equals for the new class or modify equals
method for
any new property?

Yes, that's true. To some extent, that's just "business as usual".
People updating or subclassing a particular class need to be aware of what
it's already implementing. Note that even if you were using reflection
for this particular purpose, that wouldn't obviate ths need. It would
make that particular situation immune, but the class would otherwise still
be susceptible.

That said, ironically this is an area where reflection _might_ be useful.
As a maintenance aid, you might include some "#if DEBUG" code to the
static constructor of the object that uses reflection to inspect the
class's properties and the Equals() method. Unfortunately, I don't have
the details as to how exactly you'd inspect the Equals() method, but I'm
pretty sure there's a way to go through it and see if particular
properties in the class are referenced in the method.

In that way, for debug builds, you could cross-reference the Equals()
method implementation with the properties that actually exist and put up
an assertion failure or throw an exception or whatever if it doesn't
match. This would be an acceptable overhead in debug builds (it would
only happen once per execution of the application), but would still
address the maintenance issue.

You may not find it worth bothering with though. I know that this is not
a generally used technique, and yet there are _lots_ of classes out there
that override Equals(). Obviously the maintenance overhead and risks
related to doing so are far outweighed by the benefits provided.

Pete
 
Back
Top