473,763 Members | 4,584 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Overriding == and != when overriding Equals()?

When one overrides the Equals() method of an object, one is supposed to
override GetHashCode() as well and this makes good sense. But I have seen
lots of people who do this and do not override the == and != opperators. Am
I missing something or when would one want to have different implementations
for Equals and ==?

--Ken
May 15 '06 #1
8 3746
This depends upon whether your object is a reference type or a value
type.

The "unofficial " standard for reference types is that Equals compares
the _contents_ of the objects for equality (where you define what it
means for two objects to be "equal") whereas != and == tell you whether
two variables hold references to the _same object_.

In other words, the .NET standard is that Equals compares for
equivalence, whereas == and != compare for reference equality /
inequality.

For value types (structs), it's different: in that case you _should_
override == and !=, as there's no such thing as "reference equality"
for a value type.

May 15 '06 #2
"Kenneth Baltrinic" <no************ ***@nowhere.xyz > wrote:
When one overrides the Equals() method of an object, one is supposed to
override GetHashCode() as well and this makes good sense. But I have seen
lots of people who do this and do not override the == and != opperators. Am
I missing something or when would one want to have different implementations
for Equals and ==?


If you have a mutable reference type, it may be meaningful to compare it
with other types with (say) object.Equals(o bject,object), but because
the two references do not actually refer to the same object, you still
want reference-based comparison using the '==' and '!=' operators.

If you have an immutable reference type (such as System.String), it
makes much more sense to override '==' and '!='.

-- Barry
May 15 '06 #3
You already received two replies to your earlier identical question.
Did you not read them?
--
http://www.kynosarges.de
May 16 '06 #4
Interesting,

For some reason I can't see that previous message, nor its replies in my
news reader. I just figured the network hiccuped and my orriginal post
never made it onto the board so I reposted. I just looked again and I still
can't see the orriginal. The replies on the current thread message seem to
cover the bases. Do the replies to the previous one add anything?

--Ken

"Chris Nahr" <ch************ @kynosarges.de> wrote in message
news:2k******** *************** *********@4ax.c om...
You already received two replies to your earlier identical question.
Did you not read them?
--
http://www.kynosarges.de

May 16 '06 #5
I agree and I think my code is a case of immutable objects. What I am doing
is using generics to produce strongly type Guid based object identifiers.
Basically if I declare a class A, rather than declaring an ID property as
type Guid I declare it as type Identifier<A> using the following code. This
gives me strong typing for situations where I have an overloaded method that
can act on various objects by ID but needs to know the object type as well.
Does this sound like a userful thing? I invite critisism. I like strong
typing but may be going a bit far here.

/// <summary>
/// This class encapsulates a Guid that is used as an identifier so that
strongly typed
/// Guid based identifer types can be derived from it. It is marked
abastract because
/// direct instatiation of this type would circumvent strong typing.
/// </summary>
[Serializable]
public abstract class GuidIdentifier
{
private Guid idValue;

/// <summary>
/// Creates a new GuidIdentifier object with a new Guid value.
/// </summary>
protected GuidIdentifier( )
{
this.idValue = Guid.NewGuid();
}

/// <summary>
/// Creates a new GuidIdentifier object with the provided Guid as
its underlying value.
/// </summary>
/// <param name="value">Th e Guid value to which to intitialize the
identifer.</param>
protected GuidIdentifier( Guid value )
{
this.idValue = value;
}

/// <summary>
/// Returns the actual Guid value of the identifier.
/// </summary>
public Guid Value { get { return idValue; } }

public override bool Equals( object obj )
{
if ( obj.GetType() == this.GetType() )
return GuidIdentifier. Equals( this , (
GuidIdentifier )obj );
else
return false;
}

public override int GetHashCode()
{
return this.Value.GetH ashCode();
}

public override string ToString()
{
return string.Format( "ID: {0:B}" , idValue );
}

public static bool operator ==( GuidIdentifier a , GuidIdentifier
b )
{
return GuidIdentifier. Equals( a , b );
}

public static bool operator !=( GuidIdentifier a , GuidIdentifier
b )
{
return !GuidIdentifier .Equals( a , b );
}

/// <summary>
/// Compares two GuidIdentifiers , returns true if their underlying
Guid values are the same.
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns>True if GuidIdentifier a.Value == GuidIdentifier
b.Value</returns>
public static bool Equals( GuidIdentifier a , GuidIdentifier b )
{
if ( object.Equals( a , null ) || object.Equals( b , null ) )
//will return true if both objects are null, false otherwise
return object.Equals( a , b );
else
return a.idValue == b.idValue;
}
}

/// <summary>
/// This class is a generic implementation of GuidIdentifier which
allows for
/// strongly typed Guid based identifiers that derive from a common base
class.
/// </summary>
/// <typeparam name="T">The type of the class of which
Identifier&lt;T &gt; identifies an instance.</typeparam>
public class Identifier<T> : GuidIdentifier where T : BusinessBase<T>
{
/// <summary>
/// Creates a new Identifier instance having a new Guid value;
/// </summary>
public Identifier() : base() { }

/// <summary>
/// Creates a new Identifier instance having the specified Guid
value;
/// </summary>
/// <param name="value">Th e Guid value of the identifier</param>
public Identifier( Guid value ) : base( value ) { }
}

Note I use the pattern where one defines a non-generic class that provides
for a common type for the generic sub-classes. (Is there a name for this
pattern? I see it used a lot but never see a name.)

Any comments or critisism would be appreciated.

--Ken

"Barry Kelly" <ba***********@ gmail.com> wrote in message
news:g8******** *************** *********@4ax.c om...
"Kenneth Baltrinic" <no************ ***@nowhere.xyz > wrote:
When one overrides the Equals() method of an object, one is supposed to
override GetHashCode() as well and this makes good sense. But I have
seen
lots of people who do this and do not override the == and != opperators.
Am
I missing something or when would one want to have different
implementations
for Equals and ==?


If you have a mutable reference type, it may be meaningful to compare it
with other types with (say) object.Equals(o bject,object), but because
the two references do not actually refer to the same object, you still
want reference-based comparison using the '==' and '!=' operators.

If you have an immutable reference type (such as System.String), it
makes much more sense to override '==' and '!='.

-- Barry

May 16 '06 #6
"Kenneth Baltrinic" <no************ ***@nowhere.xyz > wrote:
public override bool Equals( object obj )
{
if ( obj.GetType() == this.GetType() )
return GuidIdentifier. Equals( this , (
GuidIdentifier )obj );
else
return false;
}
Be aware that 'obj' may be null. This code will incorrectly throw a
NullReferenceEx ception in that case.
public static bool Equals( GuidIdentifier a , GuidIdentifier b )
{
if ( object.Equals( a , null ) || object.Equals( b , null ) )
//will return true if both objects are null, false otherwise
return object.Equals( a , b );
else
return a.idValue == b.idValue;
}
}


That will work, but personally, I would write this method thusly:

---8<---
return object.Referenc eEquals(a, b)
|| !object.Referen ceEquals(a, null) && a.idValue == b.idValue;
--->8---

.... since && has higher precedence than ||.

Overriding Equals, '==', '!=' and providing a static Equals() all in a
consistent way is surprisingly tricky.

-- Barry
May 16 '06 #7
Barry,

Good catch on the potential null reference, Thanks. As for the other
method, yeah I should probably use ReferenceEquals () over equals, but I
think the structure of my code is more readable. All a matter of taste
though.

"Barry Kelly" <ba***********@ gmail.com> wrote in message
news:37******** *************** *********@4ax.c om...
"Kenneth Baltrinic" <no************ ***@nowhere.xyz > wrote:
public override bool Equals( object obj )
{
if ( obj.GetType() == this.GetType() )
return GuidIdentifier. Equals( this , (
GuidIdentifier )obj );
else
return false;
}


Be aware that 'obj' may be null. This code will incorrectly throw a
NullReferenceEx ception in that case.
public static bool Equals( GuidIdentifier a , GuidIdentifier b )
{
if ( object.Equals( a , null ) || object.Equals( b , null ) )
//will return true if both objects are null, false
otherwise
return object.Equals( a , b );
else
return a.idValue == b.idValue;
}
}


That will work, but personally, I would write this method thusly:

---8<---
return object.Referenc eEquals(a, b)
|| !object.Referen ceEquals(a, null) && a.idValue == b.idValue;
--->8---

... since && has higher precedence than ||.

Overriding Equals, '==', '!=' and providing a static Equals() all in a
consistent way is surprisingly tricky.

-- Barry

May 16 '06 #8
Sounds like your newsfeed was dropping a few messages. That can
happen in busy newsgroups like this one, unfortunately.

The previous two replies were more of a general nature. They're brief
enough to I'll just add the text below. Generally, you should be able
to get a complete newsfeed from http://groups.google.com , by the way.

Lee Alexander wrote:
I would overload the == and != operators where the underlying types are my
own value types to make the underlying code simpler to read since by default
there are no overloads for them. Also the default behavour for .Equals can
(depending on its members for value types) be to do a member wise compare
using reflection which is slower than if your roll with your own comparison
methods. Note also that you cannot "override" operators which implies
polymorphism rather you can overload them.
Chris Nahr (me) wrote:[Quote from your message] >Am
I missing something or when would one want to have different implementations
for Equals and ==?


Whenever one would expect to test for reference equality of reference
types, rather than value equality.

Equals has a sister method ReferenceEquals so the jobs are clearly
differentiated , but there's only one operator== which translates to
ReferenceEqual s by default. You have to decide whether your users
would want/expect ReferenceEquals or Equals when they type ==. The
answer will be different for each type, depending on usage patterns.

--
http://www.kynosarges.de
May 17 '06 #9

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

Similar topics

4
2224
by: Rafael Veronezi | last post by:
I have some questions about override in inheritance, and virtual members. I know that you can you override a method by two ways in C#, one, is overriding with the new keyword, like: public new bool Equals(object obj) {} Another is using the override keyword, like: public override bool Equals(object obj) {}
12
6753
by: Rubbrecht Philippe | last post by:
Hi there, According to documentation I read the ArrayList.IndexOf method uses the Object.Equals method to loop through the items in its list and locate the first index of an item that returns True. Therefore, overriding the Equals method in the class definition of the items I put in the ArrayList should make the IndexOf method use my version of the Equals method?!
18
4743
by: JohnR | last post by:
From reading the documentation, this should be a relatively easy thing. I have an arraylist of custom class instances which I want to search with an"indexof" where I'm passing an instance if the class where only the "searched" property has a value. I expected to get the index into the arraylist where I could then get the entire class instance. However, the 'indexof' is never calling my overloaded, overrides Equals method. Here is the...
3
223
by: Kenneth Baltrinic | last post by:
When one overrides the Equals() method of an object, one is supposed to override GetHashCode() as well and this makes good sense. But I have seen lots of people who do this and do not override the == and != opperators. Am I missing something or when would one want to have different implementations for Equals and ==? --Ken
10
105197
by: r035198x | last post by:
The Object class has five non final methods namely equals, hashCode, toString, clone, and finalize. These were designed to be overridden according to specific general contracts. Other classes that make use of these methods assume that the methods obey these contracts so it is necessary to ensure that if your classes override these methods, they do so correctly. In this article I'll take a look at the equals and hashCode methods. ...
0
9386
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9997
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9937
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9822
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8821
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7366
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5270
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5405
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2793
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.