Reputation: 1937
interface interface1<Coordinate> where Coordinate : IComparable<Coordinate>
{
Coordinate getPosition(XYZ p);
}
static class CreateOrderOnASpaceExtensions
{
public static IOrderedEnumerable<T> OrderElements<Coordinate, T>(this interface1<Coordinate> myInterface, IEnumerable<T> elements, Func<T, XYZ> elementToPoint)
where Coordinate : IComparable<Coordinate>
=>
elements.OrderBy(
x => myInterface.getPosition(elementToPoint(x)),
Comparer<Coordinate>.Create((x, y) => x.CompareTo(y)
)
);
}
Should I really write where Coordinate : IComparable<Coordinate>
in the extension method declaration?
I already said that Coordinate
is comparable when I created interface1
.
Without that :
There is no boxing convertion or type paramater convertion from Coordinate to Comparable
Upvotes: 0
Views: 49
Reputation: 24136
I'll use ===
to show to which part the where
applies in each of your generic definitions:
interface interface1<Coordinate>
==========
where Coordinate : IComparable<Coordinate>
{
...
}
and
static class CreateOrderOnASpaceExtensions
{
public static IOrderedEnumerable<T> OrderElements<Coordinate, T>(this interface1<Coordinate> myInterface, IEnumerable<T> elements, Func<T, XYZ> elementToPoint)
==========
where Coordinate : IComparable<Coordinate>
}
Without the 2nd where
, the compiler will see that you are trying to feed an unconstrained type Coordinate
(which could then be anything) into interface1<>
, which has a constraint, making the unconstrained Coordinate
not allowed.
The fact that interface1
has a constraint does not mean that the "world" outside of it will magically also be restricted if you try to connect it; it already needs to fit before it can be allowed.
An analogy: you made a railroad which requires trains. You first need to make a train, and then you can put in on the railroad. There's no magic that makes any vehicle that you put on it a train.
Upvotes: 1