如何在C#中为所有类型的T实现IEquatable<Container<T>>?

How to implement IEquatable<Container<T>> in C# for all types T?

提问人:Treker 提问时间:2/12/2023 更新时间:2/12/2023 访问量:58

问:

我在 C# 中有一个简单的通用容器类,如下所示 -

public class Point<T>
{
    public T Data { get; }
    public string ID { get; }

    public Point(T x, string id)
    {
        this.Data = x;
        this.ID = id;
    }
}

我希望仅根据属性比较所有 Point 对象。我的问题是 - 我怎样才能实现,以便任何 Point 对象都可以相互比较?例如,可以与 进行比较,如果对象的属性相同,则这些对象将被视为相等。IDIEquatable<Point>Point<int>Point<decimal>ID

C# 泛型 IEQUATABLE

评论


答:

3赞 Sweeper 2/12/2023 #1

一个简单的方法是提取一个非泛型接口。虽然 不是必需的,但您甚至可以在此接口中包含该属性。IEquatableData

public interface IPoint {
    object? Data { get; }
    string ID { get; }
}

public class Point<T>: IPoint, IEquatable<IPoint> {
    public T Data { get; }
    
    object? IPoint.Data => Data;
    
    public string ID { get; }

    public Point(T x, string id) {
        this.Data = x;
        this.ID = id;
    }
    
    public bool Equals(IPoint? other) => ID == other?.ID;
    
    public override bool Equals(object? obj) {
        return Equals(obj as IPoint);
    }

    public override int GetHashCode() {
        return ID.GetHashCode();
    }
}

虽然需要注意的是,其他代码现在可以提供他们自己的实现和他们自己的实现,但这与您的 .这可能会导致混淆行为,例如不同意 。IPointIEquatable<IPoint>Point<T>implA.Equals(implB)implB.Equals(implA)

评论

0赞 Treker 2/12/2023
如果我提取一个具有 Id 属性的非泛型抽象类,它也可以工作吗?
1赞 Sweeper 2/12/2023
@Treker 可以,但你不能在其中包含属性,而且接口通常更灵活——一个类只能有一个超类,但可以实现多个接口。Data