Reputation: 12265
As I asked in my previous question, I got stuck with IComparer<T>
implementation.
I got an interface and class, implementing one:
public interface IRoom
{
// ...
}
public class Room : IRoom
{
// ...
}
And a comparer parent-child classes:
public abstract class RoomComparer : IComparer<Room>
{
public RoomComparer()
{
}
public abstract int Compare(Room x, Room y);
}
public class StandardMultipliedSquareMetersComparer : RoomComparer
{
public StandardMultipliedSquareMetersComparer()
{
}
public override int Compare(Room a, Room b)
{
// ...
}
}
public class SquareMetersComparer : RoomComparer
{
public SquareMetersComparer()
{
}
public override int Compare(Room a, Room b)
{
// ...
}
}
Now, I need to use my IRoom
child and a RoomComparer
child as a generic type parameters for this class:
public class Hotel<TRoom, TComparer> : IHotel, IEnumerable<TRoom>
where TRoom : class, IRoom
where TComparer : RoomComparer, new()
{
public List<TRoom> Rooms;
protected TComparer Comparer;
public Hotel(int stars, TRoom[] rooms)
{
Rooms = new List<TRoom>();
_stars = stars;
Rooms.AddRange(rooms);
Comparer = new TComparer();
Rooms.Sort(Comparer);
}
// ...
}
But compilation fails on line
Rooms.Sort(Comparer);
with two errors
Error CS1502: The best overloaded method match for `System.Collections.Generic.List.Sort(System.Collections.Generic.IComparer)' has some invalid arguments (CS1502)
Error CS1503: Argument
#1' cannot convert
TComparer' expression to type `System.Collections.Generic.IComparer' (CS1503)
From my point of view, OOP model is correct, and if an argument to Hotel
class constructor implements IRoom
, just like this: new Hotel<Room, SquareMetersComparer>
, than it should be correctly passed to RoomsComparer
class constructor and, then, RoomComparer
should be correctly passed to a List.Sort()
method. But compiler thinks in other way...
So, the question is: what's wrong?
If this helps somehow: I am using Mono 5.10.0
on Ubuntu 14.04
.
Upvotes: 0
Views: 161
Reputation: 169
TComparer
is defined as inheriting RoomComparer
.
That means that it implements IComparer
of Room
.
Your list contains instances of TRoom
, which implements IRoom
, not Room
.
Upvotes: 3
Reputation: 26298
Well first, you need to fix the errors in your SquareMetersComparer
and StandardMultipliedSquareMetersComparer
class. They are overriding public override int Compare(IRoom a, IRoom b)
but they are supposed to override public override int Compare(Room a, Room b)
.
Secondly, you want to use naked constraints between comparer and TRoom, as such:
where TRoom : class, IRoom
where TComparer : IComparer<TRoom>, new()
Also, covariance works for IComparer
, which means you can also specify such constraints, if necessary:
where TRoom : class, IRoom
where TComparer : IComparer<IRoom>, new()
Upvotes: 1