在我的Java时代,我习惯于进行.Equals()
进行比较,而不是==
(至少在我知道/已经测试过我调用.Equals()
的对象的情况下是不是空的。)
我刚刚遇到了一些C#.NET代码的问题,因为它编译好了,因为它编译好了,但是在运行时它总是返回false,但我对它编译的原因感到困惑,可以有人请解释一下? (我猜测它可能与从Equals()
继承的object
有关,但没有看到对此有好的参考。)
故事:我有一个用于过滤数据库查询的类,名为WorkFilter
,我将过滤器引擎转换为支持多值过滤器(而不是单值)过滤器)。因此,WorkFilter
的每个过滤器字段属性都已从String
转换为List<String>
,我转换了大部分代码(除了我错过的一个案例)以处理此问题,并且很好有一段时间,直到我注意到某个条件从来没有true
。
Filter类看起来像这样:
public class WorkFilter
{
public List<String> RecordType { get; set; }
public List<String> Product { get; set; }
... etc ...
}
&#34;坏&#34;代码正在这样做:
if (workFilterInstance.RecordType != null && workFilterInstance.RecordType.Equals("REQUEST"))
{
// code that never gets fired because List<String> never equals String value
}
我修复了它(基本上):
if(workFilterInstance.RecordType != null && workFilterInstance.RecordType.Contains("REQUEST"))
{
// now this can handle logic for RecordType = "REQUEST" filters
}
我是在踢我自己,因为我知道如果我使用==
代替它,它会在编译时失败,例如,如果我这样做:RecordType == "REQUEST"
因为你不能使用等于运算符来比较List<String>
和String
。
但我对.Equals()
的误解感到惊讶,因为我希望RecordType.Equals(String)
也生成编译器错误(或者至少是运行时错误,而不是总是返回false
)。我的意思是,你为什么要将List<>
与String
进行比较,为什么要编译?
我在MSDN上搜了一下,但希望有人能用简单的英语解释一下。谢谢!
答案 0 :(得分:7)
因为List<T>
是Object
而对象提供Equals实施。其定义为:
public virtual bool Equals(
Object obj
)
现在,因为传递的参数是string
,它又是一个对象,它会编译。
征求意见:
但为什么在运行时不会失败?没有保护措施 做我做的事情? -
它将返回false。它没有理由失败。 (虽然IMO,它应该显示警告)。如果您使用Resharper,您将收到警告:
可疑比较:解决方案中没有类型 继承自
答案 1 :(得分:6)
此代码进行编译,因为Equals
的{{1}}方法覆盖了System.Object
的List<T>
方法:
Equals
它不会在运行时失败,因为public virtual bool Equals(
Object obj
)
的合同需要
Equals
和x.Equals(y) returns the same value as y.Equals(x).
&#39; System.String
will return false
if it is passed something that is not a string:
Equals(Object)
如果obj是一个String,它的值与此实例相同;否则,true
。
答案 2 :(得分:1)
是;如果你得到警告或错误会更好。
然而,类型系统并不足以表达这一点 你想写
public virtual bool Equals(??? o);
其中???
表示可转换为调用该方法的限定符的任何类型。
写一个Roslyn诊断来捕捉它应该相当容易。