'interface IComparer C#
how to right use IComparer with Generics
Solution 1:[1]
Your question is a bit unclear. If compare "by room volume" means in fact compare Area() values
and you want to imeplement a corresponding comparer, you can put something like this
public sealed class ShapeComparerByArea<T> : IComparer<T> where T : IShape
{
public int Compare(T left, T right)
{
if (ReferenceEquals(left, right))
return 0;
if (left == null)
return 1;
if (right == null)
return -1;
return left.Area().CompareTo(right.Area());
}
}
If you want to define comparable Room class (which has Shape Floor) you can put it as
public class Room : IComparable<Room> {
public Room(IShape floor, double height) {
Floor = floor ?? throw new ArgumentNullException(nameof(floor));
Height = height > 0
? height
: throw new ArgumentOutOfRangeException(nameof(height));
}
public IShape Floor { get; }
public double Height { get; }
public double Volume => Floor.Area() * Height;
public int CompareTo(Room other) {
if (ReferenceEquals(this, other))
return 0;
if (other is null)
return 1;
return Volume.CompareTo(other.Volume);
}
}
Finally, RoomComparerByVolume can be
public sealed class RoomComparerByVolume : IComparer<Room> {
public int Compare(Room left, Room right) {
if (ReferenceEquals(left, right))
return 0;
if (left == null)
return 1;
if (right == null)
return -1;
return left.Volume.CompareTo(right.Volume);
}
}
Demo:
Room myRoom = new Room(
new Trapezoid() { Length1 = 5, Length2 = 7, Width = 3},
2.8);
Room myOtherRoom = new Room(
new Rectangle() { Length = 3, Width = 4 },
2.5);
Console.WriteLine(myRoom.CompareTo(myOtherRoom));
RoomComparerByVolume comparer = new RoomComparerByVolume();
Console.WriteLine(comparer.Compare(myRoom, myOtherRoom));
Solution 2:[2]
I would assume that the desired declaration should look like
public class RoomComparerByVolume<T> : IComparer<Room<T>> where T : IShape, ICloneable, IComparable{
public int Compare(Room<T> left, Room<T> right) {
...
}
That way you can compare the two rooms. But note that the two rooms need to be the same shape using this method. Also note that you need to use the same generic constraints as you are using for Room<T>.
Also note that in many cases you do not need to create a specific comparer type. Often you can use a delegate to do the actual comparison:
Comparer<Room<Trapezoid>>.Create((l, r) => l.Volume().CompareTo(r.Volume));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | JonasH |
