473,395 Members | 2,713 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Check to see if two user defined objects are equal (C# 2.0)

In C# 2.0 I need to compare instances of an object to see if they are equal
based on an id property.

The object properties are

class Cat
{
int CatId;
string CatName;
}

if (firstCat == secondCat) {
run code because CatId matches in both objects
}

I've tried override the Equals and GetHashCode methods (which never run),
implementing IComparable. I'm not to sure on how to make this code to
work. Any help is appreciated.

Nov 17 '05 #1
7 4107
I found the answer, I need to override the == and != operators.

"Jay Douglas" <ja****************@jaydouglas.com> wrote in message
news:eg**************@TK2MSFTNGP15.phx.gbl...
In C# 2.0 I need to compare instances of an object to see if they are
equal based on an id property.

The object properties are

class Cat
{
int CatId;
string CatName;
}

if (firstCat == secondCat) {
run code because CatId matches in both objects
}

I've tried override the Equals and GetHashCode methods (which never run),
implementing IComparable. I'm not to sure on how to make this code to
work. Any help is appreciated.


Nov 17 '05 #2
You shouldn't override the == and != operators for reference types in
..NET.

The "standard" (at least so far as I've read on MSDN) is that == and !=
perform reference comparisons. == returns true if and only if the two
references point to the same object instance.

You _should_ override Equals in your case, and write the following code
to do the comparison:

if (firstCat.Equals(secondCat))

Most .NET programmers expect a reference comparison when they see this:

if (firstCat == secondCat)

they're not expecting an identity comparison or a deep comparison.

Nov 17 '05 #3
It seems to be working really well.

Tell me what you think of this documentation:

http://msdn2.microsoft.com/en-us/library/ms173147.aspx

Look at the "Overriding Operator ==" section.

This is what my overridden operators look like:

public static bool operator !=(Cat catA, Cat catB)
{
return !(catA== catB);
}

public static bool operator ==(Cat catA, Cat catB)
{
if (Object.ReferenceEquals(catA, catB))
return true;

if ((object) catA== null || (object) catB == null)
return false;

if (catA.CatId == catB.CatId)
return true;
else
return false;
}

"Bruce Wood" <br*******@canada.com> wrote in message
news:11*********************@f14g2000cwb.googlegro ups.com...
You shouldn't override the == and != operators for reference types in
.NET.

The "standard" (at least so far as I've read on MSDN) is that == and !=
perform reference comparisons. == returns true if and only if the two
references point to the same object instance.

You _should_ override Equals in your case, and write the following code
to do the comparison:

if (firstCat.Equals(secondCat))

Most .NET programmers expect a reference comparison when they see this:

if (firstCat == secondCat)

they're not expecting an identity comparison or a deep comparison.

Nov 17 '05 #4
Oh, I didn't say it wouldn't work. It's just that it violates a
commonly-held convention among C# programmers, at least according to
MSDN. In fact, the link you indicated says the following:

"When a type is immutable, meaning the data contained in the instance
cannot be changed, overloading operator == to compare value equality
instead of reference equality can be useful because, as immutable
objects, they can be considered the same as long as they have the same
value. Overriding operator == in non-immutable types is not
recommended."

Which is to say that so long as your Cat class does not have (and will
never have) properties with "set" methods, and you can't construct two
Cat objects with the same CatId but differences in other properties,
you can override == and there will be no surprises for other
programmers expecting a reference comparison. Otherwise, MS doesn't
recommend that you override == for reference types.

Since I've never written a reference type that satisfies those two
conditions, I never override == for classes. I just say

if (catA.Equals(catB))

instead.

However, this all depends upon the environment in which you're
programming. If the code is never to be maintained by anyone else then
I suppose it doesn't really matter.

Structs, of course, are a whole other can of worms. I usually provide a
custom implementation of == for struct types.

Nov 17 '05 #5
Bruce,

I like where you're going w/ this and I appreciate your feedback. Cat does
have set methods for multiple different properties. Of course this
architecture needs is going to be handed off to other developers for further
development so best practices is something I'm aiming for.

Cat is strictly a data driven object. CatId is unique, at least at the data
table level. I understand that just because CatId is the same in both
objects, it doesn't mean that Name is the same.

BUT, let's say that I have two cat objects and the ID and the Name are the
same. Let's also say that I didn't override the == or != operators. So,
both properties are the same in both objects. If I run (catA == catB) in
code, this compare ALWAYS returns false even though ALL properties that
pertain to the application are identical. This lead me down that path that
I'm taking. What could possibly make my two objects the same.

Possibly this:
Cat catA = new Cat(1);
Cat catB = catA;

(catA == catB)
This should return true, but it's strictly a reference thing, not a data
thing.

So, in my case where the data, especially the key(s) is what makes an object
equal, would the overridden operator be a good practice?


"Bruce Wood" <br*******@canada.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
Oh, I didn't say it wouldn't work. It's just that it violates a
commonly-held convention among C# programmers, at least according to
MSDN. In fact, the link you indicated says the following:

"When a type is immutable, meaning the data contained in the instance
cannot be changed, overloading operator == to compare value equality
instead of reference equality can be useful because, as immutable
objects, they can be considered the same as long as they have the same
value. Overriding operator == in non-immutable types is not
recommended."

Which is to say that so long as your Cat class does not have (and will
never have) properties with "set" methods, and you can't construct two
Cat objects with the same CatId but differences in other properties,
you can override == and there will be no surprises for other
programmers expecting a reference comparison. Otherwise, MS doesn't
recommend that you override == for reference types.

Since I've never written a reference type that satisfies those two
conditions, I never override == for classes. I just say

if (catA.Equals(catB))

instead.

However, this all depends upon the environment in which you're
programming. If the code is never to be maintained by anyone else then
I suppose it doesn't really matter.

Structs, of course, are a whole other can of worms. I usually provide a
custom implementation of == for struct types.

Nov 17 '05 #6
Nope. The generally accepted practice, as the MSDN doc points out, is
to use the Equals() method call in place of an == comparison, at least
for reference types.

I'm in exactly the situation you are: I have lots of data objects that
have unique IDs of one kind or another, and for which some properties
are mutable. In my classes, the Equals method does an identity
comparison. That is, if the two CatId's are the same, then the method
returns true, even if other fields are different. In the rare situation
in which I need a deep comparison, I write another routine to do that.
I never use the == comparison, because that compares references.

I tried overriding the == operator but quickly got complaints from
FxCop (if you don't currently use it, it's a wonderful way to stay in
synch with Microsoft standards) about doing that, so I did some digging
and found (I think) the same MSDN page you did, so I removed my ==
overrides and chose to use .Equals() instead.

As I said in another thread recently, I went one step farther and had
each object implement an IKeyed interface that specified a PrimaryKey
attribute. That way each object knows its own primary key and it's much
easier to work with them in a generic fashion. However, that's fodder
for another discussion.

My understanding of == is that the idiom typically isn't used for
reference types. == is assumed by most .NET programmers to be a value
comparison, which for a reference type means comparing reference values
(aka pointers). For reference types you typically compare using
..Equals(), which tells the reader that object fields are being
compared, not just references.

Overriding == also comes with the penalty that you can't take
meaningful advantage of inheritence: you're practically damning
yourself to writing a comparison routine for every new class you build.
Yes, you can take advantage of automatic coercions up the class
hierarchy, but it's not as powerful as overriding the Equals method and
the resulting polymorphic behaviour you get. Maybe that's one of the
reasons that MS doesn't recommend overriding ==.

Nov 17 '05 #7
Bruce,

You've made a strong argument and I see the light. =) I'll rework my
methodology. Thanks for your time.

"Bruce Wood" <br*******@canada.com> wrote in message
news:11*********************@z14g2000cwz.googlegro ups.com...
Nope. The generally accepted practice, as the MSDN doc points out, is
to use the Equals() method call in place of an == comparison, at least
for reference types.

I'm in exactly the situation you are: I have lots of data objects that
have unique IDs of one kind or another, and for which some properties
are mutable. In my classes, the Equals method does an identity
comparison. That is, if the two CatId's are the same, then the method
returns true, even if other fields are different. In the rare situation
in which I need a deep comparison, I write another routine to do that.
I never use the == comparison, because that compares references.

I tried overriding the == operator but quickly got complaints from
FxCop (if you don't currently use it, it's a wonderful way to stay in
synch with Microsoft standards) about doing that, so I did some digging
and found (I think) the same MSDN page you did, so I removed my ==
overrides and chose to use .Equals() instead.

As I said in another thread recently, I went one step farther and had
each object implement an IKeyed interface that specified a PrimaryKey
attribute. That way each object knows its own primary key and it's much
easier to work with them in a generic fashion. However, that's fodder
for another discussion.

My understanding of == is that the idiom typically isn't used for
reference types. == is assumed by most .NET programmers to be a value
comparison, which for a reference type means comparing reference values
(aka pointers). For reference types you typically compare using
.Equals(), which tells the reader that object fields are being
compared, not just references.

Overriding == also comes with the penalty that you can't take
meaningful advantage of inheritence: you're practically damning
yourself to writing a comparison routine for every new class you build.
Yes, you can take advantage of automatic coercions up the class
hierarchy, but it's not as powerful as overriding the Equals method and
the resulting polymorphic behaviour you get. Maybe that's one of the
reasons that MS doesn't recommend overriding ==.

Nov 17 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

37
by: Mike Meng | last post by:
hi all, I'm a newbie Python programmer with a C++ brain inside. I have a lightweight framework in which I design a base class and expect user to extend. In other part of the framework, I heavily...
4
by: titancipher | last post by:
I have a container that I wish to allow the user to specify a custom comparison method very similar to std::less. However, I want it to function more like memcmp (returning -1 0 1), and I want to...
26
by: JGH | last post by:
How can I check if a key is defined in an associative array? var users = new array(); users = "Joe Blow"; users = "John Doe"; users = "Jane Doe"; function isUser (userID) { if (?????)
33
by: baumann.Pan | last post by:
hi all, i want to get the address of buf, which defined as char buf = "abcde"; so can call strsep(address of buf, pointer to token);
19
by: Taras_96 | last post by:
Hi everyone, How do you detect that a form element has been changed? This thread: ...
34
by: Chris | last post by:
Is there ever a reason to declare this as if(*this == rhs) as opposed to what I normally see if(this == &rhs) ?
14
by: serge calderara | last post by:
Dear all, What is the proper way to check if two object are equal ? I do not mean equal on Object type only but also object value's thnaks for help regards serge
5
by: kang jia | last post by:
hi currently i am doing car booking website. once customer booked car with us, we will give customer the booking id, thus if they would like to update or cancel, they need to type in their...
2
by: parvtb | last post by:
Thanks for your patience to read the entire post to understand my confusion I have the user-defined class "tools": class tools{ public: tools( ......) {} friend bool operator<...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.