Please help with generics

J

James

Hi there,

I've have a class called Edge, with the following signature:
class Edge : IComparable{
....
....
....

}

And another class called CompareEdge, with the following signature:
class CompareEdge<T> : IComparer<T> where T : IComparable<T>
{
....
....
....

}

However, In my test class, the following statement is not compiling:

CompareEdge<Edge> comparer = new CompareEdge<Edge>();

I'm getting the following error:
"The type 'MetroNetwork.Edge' cannot be used as type parameter 'T' in the
generic type or method 'MetroNetwork.CompareEdge<T>'. There is no implicit
reference conversion from 'MetroNetwork.Edge' to
'System.IComparable<MetroNetwork.Edge>'."

Can someone please educate me as to why this is NOT compiling and how to fix
it?

Many thanks,
J
 
J

Jon Skeet [C# MVP]

James said:
I've have a class called Edge, with the following signature:
class Edge : IComparable{
...
...
...

}

Okay. So there you're implementing the *non-generic* interface.
And another class called CompareEdge, with the following signature:
class CompareEdge<T> : IComparer<T> where T : IComparable<T>

And there you're demanding that the type parameter T is only used where
T implements the generic interface IComparable said:
However, In my test class, the following statement is not compiling:

CompareEdge<Edge> comparer = new CompareEdge<Edge>();

I'm getting the following error:
"The type 'MetroNetwork.Edge' cannot be used as type parameter 'T' in the
generic type or method 'MetroNetwork.CompareEdge<T>'. There is no implicit
reference conversion from 'MetroNetwork.Edge' to
'System.IComparable<MetroNetwork.Edge>'."

Can someone please educate me as to why this is NOT compiling and how to fix
it?

IComparable<T> and IComparable are separate interfaces - they might as
well be IFoo<T> and IBar as far as the compiler is concerned. You need
to change the Edge declaration to:

class Edge : IComparable<Edge>
{
....
}
 
M

Marc Gravell

Edge must be : IComparable<Edge> in order to meet the contraint in
ComparerEdge<Edge>

Actually, I wonder if you can lose ComparerEdge<T> completely, and
just use the regular Comparer<Edge>.Default?

Marc
 
J

James

Jon and Marc, it worked perfectly. Many thanks.

One quick question, before I changed my Edge class declaration to "class
Edge : IComparable<Edge>",
The CompareEdge seemed to compile ok for String, that is:
CompareEdge<String> comparer = new CompareEdge<String>(); worked.
When I check msdn on the String class, it appeared to implement many
interfaces BUT was not generic.

Can someone please educate me why it worked for string?
 
P

Peter Duniho

Jon and Marc, it worked perfectly. Many thanks.

One quick question, before I changed my Edge class declaration to "class
Edge : IComparable<Edge>",
The CompareEdge seemed to compile ok for String, that is:
CompareEdge<String> comparer = new CompareEdge<String>(); worked.
When I check msdn on the String class, it appeared to implement many
interfaces BUT was not generic.

Can someone please educate me why it worked for string?

The constraint you've provided isn't that the T class itself be generic.
It's simply that the T class implements the generic interface
IComparable<T>.

The String class does in fact implement IComparable<String> (well, the
docs say "IComparable<string>" but that's really the same :) ), and so
String is a valid parameter to use for T in creating a concrete instance
of the generic class CompareEdge<T>.

After all, you haven't made your Edge class generic, right? And yet, as
long as it implements IComparable<Edge>, it should work in your
CompareEdge<T> class as well.

All that said, I'm curious as to why you've made CompareEdge<T> a generic
class at all. The name implies to me that you'll only ever use it with
the Edge class. Conversely, it will be confusing to use the class with a
class that's not an edge of some sort. Do you have a variety of classes
that all represent edges in some way? If not, why is CompareEdge<T> a
generic class?

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