问一个c#的关于string类型的问题 ( 积分: 20 )

  • 主题发起人 潇洒哥
  • 开始时间

潇洒哥

Unregistered / Unconfirmed
GUEST, unregistred user!
C#中,String 类型的是值引用还是类型引用?我现在在看帮助,它说是类型引用,妈的,越看越糊涂啊。既然是类型引用,你说以下代码的结果返回值是什么?
string a="a" ; 
string b = "b";
b = a;
a ="aa";
 return b
在DELPHI中,如果是引用类型的话,那么赋值过去的就是一个地址了,而不是值了。
 
C#中,String 类型的是值引用还是类型引用?我现在在看帮助,它说是类型引用,妈的,越看越糊涂啊。既然是类型引用,你说以下代码的结果返回值是什么?
string a="a" ; 
string b = "b";
b = a;
a ="aa";
 return b
在DELPHI中,如果是引用类型的话,那么赋值过去的就是一个地址了,而不是值了。
 
c#中返回的应该是 ‘aa’字符串吧。 记不清楚了, 应该是类型应用。
 
在c#中,string从定义上讲是类型引用的,但在使用中比较特殊,和其他的类型引用不同,是按值传的,这个在csdn中有过专门的讨论,刚开始我也很迷惑
 
用ref 定义参数就可以了
 
类型引用
但是在
b=a
时,b得到的是a 的值。
string 在这样的操作时会重新分配空间,而不是用原来的空间。
所有string的操作比stringbuilder慢。
 
虽然string是个类,但是是imutable的,完全可以看成是一个值的关系,而不要看成引用。
string a, b;
b = a;
不会重新分配空间,因为你无法修改字符串里面的内容,要修改必须创建新的实例。这一点和int, float等内置类型是一样的。
至于string的操作比stringbuilder慢,我觉得谈不上。因为string类仅有的操作是:
赋值,比较。其他的方法比如substring()等等都是重新创建string类的实例。
 
你写给程序试试
 
在string类中,'='运算符被重载,功能是拷贝字符串,同string类中的
静态方法string.copy(str1)。看一下string类的实现应该就明白了
 
确切的说,'='没有被重载,对string类型的'=',是由编译器处理的。
 
以下代码的结果返回值是什么?
string a="a" ; 
string b = "b";
b = a;
a ="aa";
 return b
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
返回值肯定是"a",与DELPHI一样----[red]写复制[/red]
 
To 特尔斐:
效果和delphi是一样的,但是实现原理不是copy on write。
 
string 是一个比较特殊的引用类型
 
在C#中String是一个特殊的引用类型,但是他的使用和值类型相似!
String s = new String("aaa");
是错误的
只能这样写:
String s = new String("aaa");
为什么呢?
可以看看ILDase.exe中生成的IL代码:
ldstr "aaa"
我们知道构造一个实例的IL指令为:newobj,而ldstr是load string的意思,
也就是说实际上.NET是通过从元数据中获的的文本常量来构造String的。
也就是说还有更高效的String类型,就是StringBuilder。
====================================================================
那么他是怎么判断二者相等的呢?
比如:
String s = "aaa";
Console.WriteLine( Object.ReferenceEquals("aaa",s) );
可能会认为他会返回false,事实上返回的true;
为什么呢?
在CLR初始化时,会创建一个散列表,其中键为string类型,值为指向托管堆中string对象的引用,开始散列表为空!对于上面的代码,编译时候,她在散列表中查找每一个文本常量string,他首先会查找第一个“aaa”,因为没有找到,所以会构造一个,然后把"aaa"和指向他的引用添加到散列表中,接着查找第二个“aaa”,这一次因为可以找到,所以什么也不做;
代码开始执行了,他会在第一行发现需要一个“aaa”字符串引用,于是CLR就在散列表中查找“aaa”,当然可以找到,找到后,就把散列表中“aaa”所在的引用存储到了s中,当执行第二行代码时候,他还会执行查找的过程,并且还会找到,而且同样的把散列表中“aaa”所在的引用传出来,也就是说作为了ReferenceEquals中的第一个参数,OK,因为二者指向的应用相同,所以返回了True!
 
返回的值是:a
 
顶部