1 [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] 2 public static bool operator ==(string a, string b) 3 { 4 return Equals(a, b); 5 }
上面是用reflector查看到的重载"=="操作符的代码。
下面是用reflector查看到的实现Equals的代码。
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] public static bool Equals(string a, string b) { return ((a == b) || (((a != null) && (b != null)) && EqualsHelper(a, b))); }
按我的理解Equals方法里面的这个 "a == b" 调用的就是重载"=="操作符的方法,而重载"=="操作符的方法又是调用Equals这个方法,那这样不就会死循环?
我这样理解,也许对你有点帮助
String类重写了Object里面的Equals方法,用了比较两个字符串是否相等,这里的相等分为两种:①引用相等,②值相等
其实String里面的Equals方法是这样的:(可能反编译出来有点差异)
public static bool Equals(String a, String b) {
if ((Object)a==(Object)b) {
return true;
}
if ((Object)a==null || (Object)b==null) {
return false;
}
if (a.Length != b.Length)
return false;
else
return EqualsHelper(a, b);
}
第一次判断进行了类型转换,全部转换为Object类型,所以这里调用的是Object的Equals方法来比较,最后调用了EqualsHelper方法来实际的比较两个字符串里面包含的值是否相等,这个方法是用C语言实现的,原理是比较具体的每一个字符。所以这里不存在死循环。
==运算符最终调用的还是Equals方法
@Gabriel Zhang: 我也是想是不是反编译出来的问题,因为如果是
if ((Object)a==(Object)b)
{ return true; }
这个来判断就不存在我想的问题。
@Gabriel Zhang: 原来你贴出来的就是源码。 这个是反编译出来的问题,谢谢啦。
那是因为CLR知道这种设计模式
可以讲具体一点吗?用到哪种设计模式?
@rockljl: 不好意思,没看清楚就在瞎说。String类的Equals方法内并不是调用的重载的==,通过Reflector可以看到,a==b使用的是bne.un.s这个IL指令。而在自己的代码中这样写:
public static bool operator ==(Program a, Program b)
{
return Equals(a, b);
}
public static bool operator !=(Program a, Program b)
{
return !(a==b);
}
public static bool Equals(Program a, Program b)
{
return (a == b) || ((a != null) && (b != null));
}
肯定会死循环的。
你可以比较下两者之间的IL代码。这实际上可以看作是Reflector的Bug。