首页新闻找找看学习计划

为什么string里面的重载"=="操作符不会导致死循环?

0
悬赏园豆:20 [已解决问题] 解决于 2013-08-05 20:34
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这个方法,那这样不就会死循环?

rockljl的主页 rockljl | 初学一级 | 园豆:184
提问于:2013-08-03 11:34
< >
分享
最佳答案
0

我这样理解,也许对你有点帮助

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语言实现的,原理是比较具体的每一个字符。所以这里不存在死循环。

收获园豆:15
Rt-张雪飞 | 小虾三级 |园豆:533 | 2013-08-03 17:37

==运算符最终调用的还是Equals方法

Rt-张雪飞 | 园豆:533 (小虾三级) | 2013-08-03 17:38

@Gabriel Zhang: 我也是想是不是反编译出来的问题,因为如果是

if ((Object)a==(Object)b) 
{
return true; }

这个来判断就不存在我想的问题。

rockljl | 园豆:184 (初学一级) | 2013-08-03 19:11

@Gabriel Zhang: 原来你贴出来的就是源码。 这个是反编译出来的问题,谢谢啦。

rockljl | 园豆:184 (初学一级) | 2013-08-05 20:31
其他回答(1)
0

那是因为CLR知道这种设计模式

收获园豆:5
alby | 园豆:321 (菜鸟二级) | 2013-08-03 11:44

可以讲具体一点吗?用到哪种设计模式?

支持(0) 反对(0) rockljl | 园豆:184 (初学一级) | 2013-08-03 11:46

@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。

支持(0) 反对(0) alby | 园豆:321 (菜鸟二级) | 2013-08-03 23:49
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册