Implementing IEqualityComparer for a struct?

R

Raj Wall

Hi,

I am trying to implement the IEqualityComparer interface for a struct so I can use it as the Key for a Dictionary.

My struct declaration has:
public struct Ring : IEqualityComparer
{
....
}
and I am trying to implement the Equals and GetHashCode methods.
I thought I could use forms like:
public bool Equals(Ring X, Ring Y)
{...
}
and
public int GetHashCode(Ring X)
{...
}
But they gave errors. From the error message I thought I should try the following:

public bool System.Collections.IEqualityComparer.Equals(Ring X, Ring Y)
{...
}
and
public int System.Collections.IEqualityComparer.GetHashCode(Ring X)
{...
}

But they give "modifier 'public' is not valid for this item.

Thanks for any advice!

Regards,
Raj
 
M

Mattias Sjögren

public bool Equals(Ring X, Ring Y)
{...
}
and
public int GetHashCode(Ring X)
{...
}

Since you're implementing the non-generic version of the interface,
the parameter types have to be object rather than Ring.

But they gave errors. From the error message I thought I should try the following:

public bool System.Collections.IEqualityComparer.Equals(Ring X, Ring Y)
{...
}
and
public int System.Collections.IEqualityComparer.GetHashCode(Ring X)
{...
}

But they give "modifier 'public' is not valid for this item.

You can't specify an access modifier when using explicit
implementation. Remove the public modifier.


Mattias
 
L

Linda Liu [MSFT]

Hi Raj,

Mattias has pointed out the problem in your code, i.e. you should modify
the parameter type from Ring to object.

The interface IEqualityComparer is not generic. The generic version of this
interface is IEqualityComparer<T> in System.Collections.Generic namespace.

When implementing an interface, we could implement implicitly or
explicitly. An explicitly implemented member cannot be accessed through a
class instance, but only through an instance of the interface. When
implementing an interface implicitly, we add the modifier 'public' on the
implementation method; when implementing an interface explicitly, we
shouldn't add any modifier on the implementation method.

For more information on explicit interface implementation, you may read the
following MSDN document:

'Explicit Interface Implementation (C# Programming Guide)'
http://msdn2.microsoft.com/en-us/library/ms173157(VS.80).aspx

In fact, intellisense in VS05 provides an option to help you implement an
interface while working in the Code Editor. For more information how to do
this, please read the following document:

'How to: Implement Interface'
http://msdn2.microsoft.com/en-us/library/tx1s9z1w(VS.80).aspx

At last, because Object class has a method called Equals, you'd better
implement the IEqualityComparer interface explicitly to avoid the potential
confusion.

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
R

Raj Wall

Linda, Mattias, hi,

Thanks for your help! My apologies for still not quite getting it.

I changed my struct definition to include the specific interface:

public struct Ring : System.Collections.Generic.IEqualityComparer<Ring>
{...}

and tried also being explicit with the method definition:
bool System.Collections.Generic.IEqualityComparer<Ring>.Equals(Object mX,
Object mY)
{...}

then I get the error
"System.Collections.Generic.IEqualityComparer<Ring>.Equals in explict
interface declaration is not a member of interface"

If I remove the "System.Collections.Generic.IEqualityComparer<Ring>" I just
get an error that I did not implement the interface member at all.

Thanks again for your advice!

Regards,
Raj
 
L

Linda Liu [MSFT]

Hi Raj,

Thank you for your quick response.

For non-generic interface IEqualityComparer, its methods's parameters are
of type object. For generic interface IEqualityComparer<T>, its methods'
parameters are of type T.

The following is a sample.

struct Ring : IEqualityComparer
{
bool IEqualityComparer.Equals(object x, object y)
{
...
}
int IEqualityComparer.GetHashCode(object obj)
{
...
}
}

struct Ring : IEqualityComparer<Ring>
{
bool IEqualityComparer<Ring>.Equals(Ring x, Ring y)
{
...
}
int IEqualityComparer<Ring>.GetHashCode(Ring obj)
{
...
}
}

In fact, you needn't write the above stubs by yourself when you're using
VS05. Intellisense has provided an option to help you generate the stubs.

To do this, in the code editor, put the input focus within the word
'IEqualityComparer' and click the right mouse button. Choose 'Implement
Interface | Implement Interface Explicitly' from the context menu. Then the
stubs for explicit implementation are generated automatically.

Hope this helps.
If you have anything unclear, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support
 
N

Nicholas Paldino [.NET/C# MVP]

Raj,

In addition to the advice given by Mattias and Linda, it should also be
noted that you shouldn't be implementing the IEqualityComparer interface on
the type that you want to compare two instances of. This interface is meant
to be implemented on a type outside of the instances being compared. The
reason for this is in case one or both of the instances is/are null.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hi,

I am trying to implement the IEqualityComparer interface for a struct so I
can use it as the Key for a Dictionary.

My struct declaration has:
public struct Ring : IEqualityComparer
{
....
}
and I am trying to implement the Equals and GetHashCode methods.
I thought I could use forms like:
public bool Equals(Ring X, Ring Y)
{...
}
and
public int GetHashCode(Ring X)
{...
}
But they gave errors. From the error message I thought I should try the
following:

public bool System.Collections.IEqualityComparer.Equals(Ring X, Ring Y)
{...
}
and
public int System.Collections.IEqualityComparer.GetHashCode(Ring X)
{...
}

But they give "modifier 'public' is not valid for this item.

Thanks for any advice!

Regards,
Raj
 
R

Raj Wall

Nicholas, hi,

The reason I was implementing on the type was that I was hoping to snag the
equality comparison request that Dictionary would be making. I'm not sure
where else Dictionary would be looking in order to compare two keys? Thanks
for your help and advice!

Regards,
Raj
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top