首页 > 解决方案 > 在 C# 中使用泛型类型时使用正确的 Equals 方法

问题描述

我有课:

public class A : IEquatable<A>
{
  ...
  public bool Equals(A data) { ... }
}

public class B
{
   ...
}

和自定义作业的通用类

public class CommonFilter<T>
{
   public T GetBy(T data) {
      var item = list.FirstOrDefault(s=> s?.Equals(data) == true);
      ...
   }
}

list如果List<T>类型。

CommonFilter<A> cmA = GetFilter();
var result = cmA.GetBy(data);

在调试模式下,如果我有类似的对象CommonFilter<A>,我希望在 LINQ 中使用类中的Equals方法A,但事实并非如此。

如何做到这一点?

标签: c#

解决方案


正如 Jasper 指出的那样,您缺少一个通用约束:

public class CommonFilter<T> where T : IEquatable<T>

其他答案中没有解释的是为什么需要它。

请记住,编译器需要s?.Equals(data)在编译时解析调用。在您的代码中,编译器一无所知T,因此将调用解析为 any 的唯一可能候选者Tobject.Equals默认为引用比较。

另一方面,如果您定义了约束,则编译器知道任何给定T的必须实现更具体的IEquatable<T>.Equals,并将解析对该方法的调用。

如果定义约束是一项重大更改,或者您根本无法实现它,因为您还需要处理引用相等性合适的数据,那么您可以在内部分支GetBy是否T实现IEquatable<T>,类型检查泛型类型通常是一个危险信号,但是在这种特定情况下,这可能是合理的。

如果可能的话,我更喜欢第一个选项,因为这样你特别禁止使用GetBy未实现的类型IEquatable<T>


推荐阅读