Dictionary<T,U>

T

Tony Johansson

Hi!

My first question:
If I don't provide any IEqualityComparer to the constructor of the
Dictionary how will the Dictionary
doing the compare of keys ?

My second question is it always important to supply an IEqualityComparer as
argument to the Dictionary ?

public static void Main()
{
Dictionary<Car,string> dict = new Dictionary<Car,string>();
}


public class Car
{
private string name;
private int speed;
....
}

//Tony
 
P

Peter Duniho

Tony said:
Hi!

My first question:
If I don't provide any IEqualityComparer to the constructor of the
Dictionary how will the Dictionary
doing the compare of keys ?

System.Object.GetHashCode() and System.Object.Equals(), which may or may
not be overridden in the class used as TKey.
My second question is it always important to supply an IEqualityComparer as
argument to the Dictionary ?

No.

Pete
 
T

Tony Johansson

Peter Duniho said:
System.Object.GetHashCode() and System.Object.Equals(), which may or may
not be overridden in the class used as TKey.


No.

Pete

At the end is some text from the e-learning that I use.
I just wonder what this sentence mean ?
"If you do not specify an implementation, the default generic equality
comparer EqualityComparer.Default is used. The EqualityComparer.Default is
the public read-only version of EqualityComparer and returns the default
generic argument. It also provides a base class for implementations of the
IEqualityComparer generic interface."

I mean if I don't specify an implementation meaning passing no argument to
the Dictionary c-tor
then your answer(row below) should be valid and not what the above sentence
say.
System.Object.GetHashCode() and System.Object.Equals(), which may or may
not be overridden in the class used as TKey.
To determine whether keys are equal, the generic Dictionary class needs an
equality implementation of the generic IEqualityComparer interface. For
this, it uses a constructor that accepts the comparer parameters. If you do
not specify an implementation, the default generic equality comparer
EqualityComparer.Default is used. The EqualityComparer.Default is the public
read-only version of EqualityComparer and returns the default generic
argument. It also provides a base class for implementations of the
IEqualityComparer generic interface.



//Tony
 
P

Peter Duniho

Tony said:
Peter Duniho said:
System.Object.GetHashCode() and System.Object.Equals(), which may or may
not be overridden in the class used as TKey. [...]

At the end is some text from the e-learning that I use.
I just wonder what this sentence mean ?
"If you do not specify an implementation, the default generic equality
comparer EqualityComparer.Default is used. The EqualityComparer.Default is
the public read-only version of EqualityComparer and returns the default
generic argument. It also provides a base class for implementations of the
IEqualityComparer generic interface."

I mean if I don't specify an implementation meaning passing no argument to
the Dictionary c-tor
then your answer(row below) should be valid and not what the above sentence
say.

They say the same thing. Take a look at the implementation of the
default EqualityComparer. Or better yet, just check the documentation.
From http://msdn.microsoft.com/en-us/library/ms224763.aspx:

The Default property checks whether type T implements the
System.IEquatable<T> generic interface and if so returns an
EqualityComparer<T> that uses that implementation. Otherwise
it returns an EqualityComparer<T> that uses the overrides of
Object.Equals and Object.GetHashCode provided by T.

the GetHashCode() said:
To determine whether keys are equal, the generic Dictionary class needs an
equality implementation of the generic IEqualityComparer interface.

But YOU do not need to provide one. It is NOT important to ALWAYS
supply one. As long as you are satisfied with the existing
implementation of IEquatable<T> or the overrides of GetHashCode() and
Equals() in the class you are using for TKey, there's no need to provide
an explicit comparer. The default one will do just what you want.

Pete
 
T

Tony Johansson

Peter Duniho said:
Tony said:
Peter Duniho said:
System.Object.GetHashCode() and System.Object.Equals(), which may or may
not be overridden in the class used as TKey. [...]

At the end is some text from the e-learning that I use.
I just wonder what this sentence mean ?
"If you do not specify an implementation, the default generic equality
comparer EqualityComparer.Default is used. The EqualityComparer.Default
is the public read-only version of EqualityComparer and returns the
default generic argument. It also provides a base class for
implementations of the IEqualityComparer generic interface."

I mean if I don't specify an implementation meaning passing no argument
to the Dictionary c-tor
then your answer(row below) should be valid and not what the above
sentence say.

They say the same thing. Take a look at the implementation of the default
EqualityComparer. Or better yet, just check the documentation. From
http://msdn.microsoft.com/en-us/library/ms224763.aspx:

The Default property checks whether type T implements the
System.IEquatable<T> generic interface and if so returns an
EqualityComparer<T> that uses that implementation. Otherwise
it returns an EqualityComparer<T> that uses the overrides of
Object.Equals and Object.GetHashCode provided by T.

the GetHashCode() and said:
To determine whether keys are equal, the generic Dictionary class needs
an equality implementation of the generic IEqualityComparer interface.

But YOU do not need to provide one. It is NOT important to ALWAYS supply
one. As long as you are satisfied with the existing implementation of
IEquatable<T> or the overrides of GetHashCode() and Equals() in the class
you are using for TKey, there's no need to provide an explicit comparer.
The default one will do just what you want.

Pete

Yes I understand but why do they write in the docs The Default property
checks whether type T implements the
System.IEquatable<T> generic interface and if so returns an
EqualityComparer<T> that uses that implementation.

I mean if type T implement the System.IEquatable<T> what do they mean when
they say and if so returns an EqualityComparer<T> that uses that
implementation ???

//Tony
 
R

Raja R Harinath

Hi,


[snip]
Yes I understand but why do they write in the docs The Default property
checks whether type T implements the
System.IEquatable<T> generic interface and if so returns an
EqualityComparer<T> that uses that implementation.

I mean if type T implement the System.IEquatable<T> what do they mean when
they say and if so returns an EqualityComparer<T> that uses that
implementation ???

It's non-trivial to do such type-based specialization with C# generics.
The implementers of EqualityComparer<T>.Default had to jump through
hoops (System.Reflection), and maybe they wanted to document their
travails.

The para you quoted is probably hinting that the comparer object defined
by EqualityComparer<T>.Default is determined at run-time, not at
compile-time (or JIT time).

- Hari
 
P

Peter Duniho

Tony said:
Yes I understand but why do they write in the docs The Default property
checks whether type T implements the
System.IEquatable<T> generic interface and if so returns an
EqualityComparer<T> that uses that implementation.

The literal answer to your question is "they wrote that in the docs,
because it's true".

But surely that's not really the information you're looking for. Are
you asking why did they bother to tell you what the implementation is?
Or are you asking why the implementation is the way it is?

Because the code is more efficient that way.

There are (at least) two choices:

– Return an EqualityComparer<T> that, every time you call Equals() or
GetHashCode(), attempts to cast the parameter(s) to IEquatable<T> and
conditionally uses that or the System.Object methods as appropriate.

– Check T when the EqualityComparer<T>.Default property value is
retrieved, and if T implements IEquatable<T>, return an implementation
of EqualityComparer<T> that always casts the parameter(s) to
IEquatable<T> when Equals() and GetHashCode() are called, and if T does
not implement IEquatable<T>, return an implementation of
EqualityComparer<T> that simply calls the System.Object methods.

In other words, the choice is between doing the type-based check on
every single comparison and hash-code calculation, and doing it once.

Surely you can agree that it's better to just do it once.

Pete
 

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