先来说说string类型,在.net中,string是引用类型,如string str="hello",str变量会存放在栈上,"hello"会存放在堆上,str存放的值是堆上"hello"的首地址,即str指向"hello".
在.net中,==比较的是基本类型,也就是值类型,也就是变量的值是否相等;当如果我们要比较引用类型时,需要equals,它比较的是引用类型所指对象是否一致,也就是说是否指向同一个对象,引用类型存放的地址是否相等.string 虽然是引用类型,但是CLR对其进行了优化,对==运算符进行重载,比较的是字符串的值,对equals进行了重写,比较的也是字符串的值.同时CLR提供了字符串驻留的功能,在内存中有个字符串表来存放字符串,对string str1="hello"方式定义的字符串,先在字符串表中查找是否有字符串"hello",有直接指向该内存地址,无则重新开辟一块内存来存放"hello";而对于string str2=new string(new char[]{'h','e','l','l','o'})方式定义的字符串,不管字符串表中是否存在字符串"hello",都重新开辟一块内存来存放"hello".字符串驻留可以节省内存空间.
接下来说说""和string.empty的区别.string str3="",str3上存放了一个4字节的地址,该地址指向堆内存的一块长度为0的区域,也就是说为str3分配了内存空间,只不过该内存空间长度为0,存放空字符.实际上Empty是string类中的一个静态的只读字段,他的定义是这样的:public static readonly String Empty = "";
也就是说string str4=string,empty也是在str4上存放了一个4字节的地址,该地址指向堆内存的一块长度为0的区域,该区域存放空字符串"".也就是说""和string,empty效果是一样的.那么,它们的区别在哪里呢?在性能上.string.empty在语法上进行了优化,当编译msil时,会直接把改字符串引用指向系统""空间上;而string str3=""则先在字符串表查找是否有"",然后才指向它.所以string.empty的性能优于"".当我们判断字符串是否为空时,性能上str.length==0>str==string.empty>str=="".
最后在说下null,这个很简单,就是只声明了引用类型,但是并没有为其分配内存空间,也就是说它不指向任何地址.
obj1.equals(obj2)可能比较的是值,也可能是地址,或者是其他的,因为它声明为虚函数,是可以重写的,如string类的equals.而referencequals(obj1,obj2)比较的是对象的地址,是不可以重写的.