接口 IComparer C#

interface IComparer C#

如何正确使用 IComparer 和泛型

你的问题有点不清楚。如果比较“按房间体积”实际上意味着比较Area()值 并且你想实现一个相应的比较器,你可以放这样的东西

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());     
    }        
}

如果你想定义可比较的Room class(其中有Shape Floor)你可以把它写成

  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);
    }
  }

终于RoomComparerByVolume可以

  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);
    }
  }

演示:

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));

我认为所需的声明应该类似于

public class RoomComparerByVolume<T> : IComparer<Room<T>> where T : IShape, ICloneable, IComparable{
    public int Compare(Room<T> left, Room<T> right) {
        ...
    }

这样你就可以比较两个房间了。但注意使用此方法需要两个房间的形状相同。另请注意,您需要使用与 Room<T>.

相同的通用约束

另请注意,在许多情况下,您不需要创建特定的比较器类型。通常您可以使用委托来进行实际比较:

Comparer<Room<Trapezoid>>.Create((l, r) => l.Volume().CompareTo(r.Volume));