比较两个不同类型对象的正确方法

Proper way to compare two objects of different types

我正在使用一个包含服务的库,该服务在另一个应用程序中创建或删除对象时发出通知。这些对象属于 A 类型,其中包含很多我在应用程序中不需要的信息。

所以在我的应用程序中,我创建了一个类型 B,它是一个轻量级的 A 类型。当我收到服务通知对象 A 已被删除时,我必须将类型 A 中删除的项目与我的类型 B 进行匹配才能删除正确的对象。

我是否应该覆盖 B 类型的 Equals 方法并编写如下内容:

public override bool Equals(object obj) {
    if (base.Equals(obj)) return true; //check for reference
    B lightweightObj = obj as B;

    if (alarm == null) {
        A objFromService = obj as A;
        if (objFromService == null) return false;
        return objFromService.Class == this.ClassId &&
                objFromService.Group == this.GroupId &&
                objFromService.Name.Equals(this.Name) &&
                objFromService.Time == this.Time &&
                objFromService.Projectname.Equals(this.Project.Project.Name);
    } else {
        return lightweightObj.ClassId == this.ClassId &&
               lightweightObj.GroupId == this.GroupId &&
               lightweightObj.Name.Equals(this.Name) &&
               lightweightObj.Time == this.Time &&
               lightweightObj.Project == this.Project;
    }
}

或者我应该创建一个简单的函数,在参数中接受一个 A 类型的对象并返回一个布尔值?

我希望能够做类似的事情:

B matchingBObject = MyObjects.FirstOrDefault(a => a.Equals(args.TheAObject));
if(matchingBObject != null) {
    MyObjects.Remove(matchingBObject);
}

Equals 函数应该只比较两个相同类型的对象还是可以比较两个完全不相关的类型?

你绝对不应该这样做。相反,正如您所建议的,您应该将此逻辑简单地写成一个单独的方法。

至少,这样的代码会令人困惑,这会导致错误,这些错误通常很难修复,因为没有其他人(或六个月后的你)查看代码会猜到有人会这样做像这样。

更有问题的是,由于大多数人都理解平等的概念,所以它是反身的。也就是说,如果对象 A 等于对象 B,则对象 B 等于对象。但是,如果您像这样设置覆盖,那将是不正确的。相反,即使 a.Equals(b)trueb.Equals(a) 也可能不是。

同样,至少这很令人困惑。但是,如果您最终尝试在散列 table 中使用这种实现,或者尝试在列表或其他集合中查找元素,那么情况会更糟。在这些场景中,假定并依赖于相等性的反身性,并且像上面这样的代码根本无法工作。

拜托,为了你自己的理智和他人的理智,写一个常规的方法来做出这个决定,比如LightweightMatchesServiceObject()或者像这样清晰易懂的东西。