549

就是我了...

导航

<2012年5月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

公告

IT闲人 点击发送消息给对方点此发送QQ消息

统计

文章分类

档案

随笔分类

相册

Borland

myself

程序相关

朋友

登录

2007年4月16日 #

关于String 的==操作和Equals的比较

昨天上课,提到了string的==和Equals的问题,当时没有实验条件,讨论也就停留在表面层次。今天调试一下,得到如下结果。

private void Button7_Click(object sender, EventArgs e)
        {
            string a;
            string b;
            a = "hello";
            b = "hello";
            //第一步,测试 a==b
            /*
                a = "hello";
            00000033 8B 05 DC 30 3E 02 mov         eax,dword ptr ds:[023E30DCh]
            00000039 8B F8            mov         edi,eax
                b = "hello";
            0000003b 8B 05 DC 30 3E 02 mov         eax,dword ptr ds:[023E30DCh]
            00000041 8B D8            mov         ebx,eax
             * 这里编译器做了优化,无论比较值还是比较地址,都是相等的,因此,此测试没有什么意义
             */
            if (a == b)
            {
                MessageBox.Show("a==b");
            }
            else
            {
                MessageBox.Show("a!=b");
            }


            //第二步,绕开编译器的优化,测试 a==b
            string c = "hello world";

            /*
            
            00000089 8B FE            mov         edi,esi
            0000008b 6A 05            push        5   
            0000008d 8B 4D B4         mov         ecx,dword ptr [ebp-4Ch]
            00000090 33 D2            xor         edx,edx
            00000092 39 09            cmp         dword ptr [ecx],ecx
            00000094 E8 AB F7 FB 77   call        77FBF844                  //SubString
            00000099 89 45 AC         mov         dword ptr [ebp-54h],eax
            0000009c 8B 55 AC         mov         edx,dword ptr [ebp-54h]
            0000009f 8B CF            mov         ecx,edi
            000000a1 E8 22 2D FF 77   call        77FF2DC8                  //比较过程,下面有详细描述
            000000a6 8B F8            mov         edi,eax
            000000a8 85 FF            test        edi,edi
            000000aa 0F 94 C0         sete        al  
            000000ad 0F B6 C0         movzx       eax,al
            000000b0 8B D8            mov         ebx,eax
            000000b2 85 DB            test        ebx,ebx
            000000b4 75 11            jne         000000C7
             *
             Call Stack
             * > mscorlib.dll!string.EqualsHelper(string strA, string strB = "hello") + 0x20 bytes 
                  mscorlib.dll!string.Equals(string a, string b) + 0x1a bytes 
                  mscorlib.dll!string.operator ==(string a, string b) + 0x5 bytes 
            从这里可以看到 “==”已经被override了
            这里可以看到,是根据字符串内容比较的,不是比较地址
            0000007d 8B 02            mov         eax,dword ptr [edx]
            0000007f 3B 01            cmp         eax,dword ptr [ecx]
            00000081 75 0D            jne         00000090
             */
            if (a == c.Substring(0, 5))
            {
                MessageBox.Show("a == c.Substring(0, 5)");
            }
            else
            {
                MessageBox.Show("a != c.Substring(0, 5)");
            }

        }

        private void button8_Click(object sender, EventArgs e)
        {
            string a = "hello";
            string b = null;

            /*
             * Call Stack
             > mscorlib.dll!string.EqualsHelper(string strA = "hello", string strB = "hello") 
                mscorlib.dll!string.Equals(string value) + 0x10 bytes 
            */

            if (a.Equals("hello"))
            {
                MessageBox.Show("a.Equals(\"hello\")");
            }
            else
            {
                MessageBox.Show("not a.Equals(\"hello\")");
            }

            if (a.Equals(null))
            {
                MessageBox.Show("a.Equals(null)");
            }
            else
            {
                MessageBox.Show("not a.Equals(null)");
            }

            if (a.Equals(b))//Get an exception in 2005, not equal in Orcas
            {
                MessageBox.Show("a.Equals(b)");
            }
            else
            {
                MessageBox.Show("not a.Equals(b)");
            }


            if (((string)null).Equals(null))//Get an exception
            {
                MessageBox.Show("null.Equals(null)");
            }
            else
            {
                MessageBox.Show("not null.Equals(null)");
            }

            if (b.Equals(b))//Get an exception
            {
                MessageBox.Show("b.Equals(b)");
            }
            else
            {
                MessageBox.Show("not b.Equals(b)");
            }
        }

结论,两者没有本质区别,最终都是调用mscorlib.dll!string.EqualsHelper

细微的差别还是有的,那就是调用Equals的类不能为空。貌似这句话是废话,hoho.

从效率上讲,==多调用一层函数,充其量是多了两个move,和一个call,可以忽略不计。

不过在2005下调用Equals时,参数不能为null,否则会抛异常,没跟踪,记住就可以了,具体原因自己看汇编吧。

以上列出的是Orcas的编译结果。

12:29 | 评论 (0)


请不要发表可能给我们带来伤害的政治言论,谢谢配合