C# 为什么List.Equals(String)编译?

C# 为什么List.Equals(String)编译?,c#,string,generics,C#,String,Generics,在Java时代,我习惯于使用.Equals进行比较,而不是==至少在我知道/已经测试了调用.Equals的对象是否为null的情况下 我刚刚遇到了一些C.NET代码的问题,这些代码在一些版本中被遗漏了,因为它编译的很好,但在运行时它总是返回false,但我有点困惑它为什么编译,有人能解释一下吗?我猜这可能与从对象继承的相等有关,但并没有看到一个很好的参考 故事:我有一个用于过滤数据库查询的类,称为WorkFilter,我将过滤器引擎转换为支持多值过滤器,而不仅仅是单值过滤器。所以WorkFilt

在Java时代,我习惯于使用.Equals进行比较,而不是==至少在我知道/已经测试了调用.Equals的对象是否为null的情况下

我刚刚遇到了一些C.NET代码的问题,这些代码在一些版本中被遗漏了,因为它编译的很好,但在运行时它总是返回false,但我有点困惑它为什么编译,有人能解释一下吗?我猜这可能与从对象继承的相等有关,但并没有看到一个很好的参考

故事:我有一个用于过滤数据库查询的类,称为WorkFilter,我将过滤器引擎转换为支持多值过滤器,而不仅仅是单值过滤器。所以WorkFilter的每个filter字段属性都从String转换为List,我转换了大部分代码,除了我没有处理的一个例子之外,这在一段时间内都很好,直到我注意到某个条件从来都不是真的

筛选器类如下所示:

public class WorkFilter
{
    public List<String> RecordType { get; set; }
    public List<String> Product { get; set; }
    ... etc ...
}
我之所以自责是因为我知道,如果我使用==替代,它在编译时就会失败,例如,如果我这样做:RecordType==REQUEST,因为您不能使用相等运算符来比较列表和字符串

但我对.Equals的误解让我感到惊讶,因为我希望RecordType.equalString也会生成编译器错误或至少是运行时错误,而不是总是返回false。。。我的意思是,你们为什么要把列表和字符串进行比较,为什么要编译它


我浏览了一下MSDN,希望有人能用简单的英语解释一下。谢谢

之所以编译此代码,是因为列表的Equals方法是对以下方法的Equals方法的重写:

它不会在运行时失败,因为Equals契约要求

x.Equals(y) returns the same value as y.Equals(x).
和System.String的EqualObject:

如果obj是字符串且其值与此实例相同,则为true;否则,错误


之所以编译此代码,是因为列表的Equals方法是对以下方法的Equals方法的重写:

它不会在运行时失败,因为Equals契约要求

x.Equals(y) returns the same value as y.Equals(x).
和System.String的EqualObject:

如果obj是字符串且其值与此实例相同,则为true;否则,错误

因为列表是一个对象,对象提供了实现。定义为:

public virtual bool Equals(
    Object obj
)
现在,由于传递的参数是一个字符串,而该字符串又是一个对象,因此它可以编译

请发表评论:

但为什么这不会在运行时失败呢?没有预防措施吗 做我做过的事?——

它将返回false。它没有失败的理由。虽然在国际海事组织,它应该显示一个警告。如果使用Resharper,您将收到警告:

可疑比较:解决方案中没有 继承自两者

因为列表是一个对象,对象提供了实现。定义为:

public virtual bool Equals(
    Object obj
)
现在,由于传递的参数是一个字符串,而该字符串又是一个对象,因此它可以编译

请发表评论:

但为什么这不会在运行时失败呢?没有预防措施吗 做我做过的事?——

它将返回false。它没有失败的理由。虽然在国际海事组织,它应该显示一个警告。如果使用Resharper,您将收到警告:

可疑比较:解决方案中没有 继承自两者


对,;如果你能因此得到警告或错误,那就更好了

但是,类型系统不够丰富,无法表达这一点。 你想写作吗

public virtual bool Equals(??? o);
哪里???表示可转换为调用方法的限定符的任何类型


写一个Roslyn诊断来捕捉这一点应该相当容易;如果你能因此得到警告或错误,那就更好了

但是,类型系统不够丰富,无法表达这一点。 你想写作吗

public virtual bool Equals(??? o);
哪里???表示可转换为调用方法的限定符的任何类型


编写一个Roslyn诊断程序来捕捉这一点应该相当容易。

因为List是一个对象,而对象提供了Equals实现。但是为什么在运行时不会引发异常?@没什么必要您需要什么样的保护?它将返回false。这还不够吗。或者使用==获取编译时错误,为什么会失败?它只会返回false,因为string类型的对象不能等于List类型的对象。@L.B在不需要重新harper的情况下执行此操作时,良好的保护将是一个警告。然而,我不希望经常做这种改变。我认为不值得争论的是,如果使用Equals比较两个不同的类实例永远不会返回true,那么为什么还要进行比较,为什么不抛出一个异常,因为[显然?]是无意的。在这种情况下,只是我在重构时没有执行“查找所有引用”。我可能要发布一个后续问题:你为什么要使用.Equals to compa
是不同类型的对象吗?可能是多态性?因为List是一个对象,而对象提供了Equals实现。但为什么它不会在运行时引发异常?@Nothing是必需的您需要什么样的保护?它将返回false。这还不够吗。或者使用==获取编译时错误,为什么会失败?它只会返回false,因为string类型的对象不能等于List类型的对象。@L.B在不需要重新harper的情况下执行此操作时,良好的保护将是一个警告。然而,我不希望经常做这种改变。我认为不值得争论的是,如果使用Equals比较两个不同的类实例永远不会返回true,那么为什么还要进行比较,为什么不抛出一个异常,因为[显然?]是无意的。在这种情况下,只是我在重构时没有执行“查找所有引用”。我可能要发布一个后续问题:为什么要使用.Equals来比较不同类型的对象?也许吧?是的,我愿意接受一个警告。我现在必须用谷歌搜索Roslyn诊断:是的,我愿意接受一个警告。我现在必须用谷歌搜索Roslyn诊断:谢谢你关于resharper的提示和良好的解释谢谢你关于resharper的提示和良好的解释+1谢谢,公平地说,你先回答了,但我发现Habib的回答更符合我的知识水平+1谢谢,公平地说,你先回答了,但我发现哈比卜的回答更符合我的知识水平