Reputation:
I don't understand what is going on here...
I've got the following error:
The type 'TestApp.TestVal'
cannot be used as type parameter 'T'
in the generic type or method 'TestApp.SomeClass<T>'
. There is no boxing conversion from 'TestApp.TestVal'
to 'System.IComparable<TestApp.TestVal>'
.
This error happens for the following code:
public enum TestVal
{
First,
Second,
Third
}
public class SomeClass<T>
where T : IComparable<T>
{
public T Stored
{
get
{
return storedval;
}
set
{
storedval = value;
}
}
private T storedval;
}
class Program
{
static void Main(string[] args)
{
//Error is on the next line
SomeClass<TestVal> t = new SomeClass<TestVal>();
}
}
Since the enum is an int
by default and int's implement the IComparable<int>
interface it seems like there shouldn't be an error....
Upvotes: 6
Views: 4788
Reputation: 238048
Enum doesn't implement IComparable<T>
, but it does implement IComparable
. So an enum can be the T in a where clause like:
where T : IComparable
but this gives an error:
where T : IComparable<T>
And then I suppose you'd like SomeClass to be comparable. To do that, it would have to implement IComparable itself.
Here's an example of both (using a public member to keep the code simple):
public class SomeClass<T>
: IComparable<SomeClass<T>>
where T : IComparable
{
public T storedval;
public int CompareTo(SomeClass<T> other)
{
return storedval.CompareTo(other.storedval);
}
}
Upvotes: 1
Reputation: 233125
Enums do not derive from System.Int32s - they derive from System.Enum, which doesn't implement IComparable<int>
(it does implement IComparable
, though).
Although an enum's underlying value is an int by default, the enum itself isn't. Thus, there is no conversion between the two.
Upvotes: 5
Reputation: 1062502
Firstly, I'm not sure whether it is sensible to use IComparable<T>
with an enum... IEquatable<T>
, sure - but comparison?
As a safer alternative; rather than mandate the IComparable<T>
with the generic constraint, perhaps use Comparer<T>.Default
inside the class. This has the advantage of supporting IComparable<T>
and IComparable
- and it means you have less constraints to propagate.
For example:
public class SomeClass<T> { // note no constraint
public int ExampleCompareTo(T other) {
return Comparer<T>.Default.Compare(Stored, other);
}
... [snip]
}
This works fine with the enum:
SomeClass<TestVal> t = new SomeClass<TestVal>();
t.Stored = TestVal.First;
int i = t.ExampleCompareTo(TestVal.Second); // -1
Upvotes: 9
Reputation: 88345
In C# enums implement IComparable
, but not the generic IComparable<T>
. I'm not sure why this is, but maybe you could switch to the non-generic IComparable
in your where clause.
Upvotes: 0