string类型属于引用类型, string overrides its == and != operator to compare the content:public static bool operator ==(string a, string b) { return string.Equals(a, b); }
to: saucer(思归/MVP) 这不是照样显示了值类型的特点了吗,,一般的引用类型根本不用加ref参数,,只有对于值类型的需要传递他的地址时才用ref,,不是吗??
Uri u = new Uri("http://www.163.com/"); ReplaceUri(u); Console.WriteLine(u.ToString());------------------void ReplaceUri(Uri u) { u = new Uri("http://127.0.0.1/"); }输出http://www.163.com/ 所以引用类型在这里也不会变 加个ref吧
no, pass by value, means the pointer value is passed in, not a copy of the value of the content is passed in>>>一般的引用类型根本不用加ref参数wrong, not in .NET, if you want to change a reference a variable points to, you need to use ref or out
see the comments by "Sunmast(速马在北京)", string is not a fixed size type like those ValueTypes and potentially very large. Imagine it is a ValueType, and pass a string around methods, how many copies could be created....
不过String类有重写了Equal
string本质上是引用类型
但是有的时候又有值类型的特点
在string作为参数传递时,也确实是按照引用传递的(传地址)至于为什么这么设计...去问CLR小组得了,呵呵,个人猜测的是:
string本质上还是一个char[],所以作为数组这肯定是引用类型(在托管堆上创建对象)
但是MS考虑到string对象非常的常用,又想把string也作为基本类型支持,但是使用上不太方便,所以重写了==和!=操作符,使其看上去像个值类型
{ string str="string";
test(str);
textBox1.Text=str;
}public void test(string stt)
{
stt="hello,lgg";
}textBox1显示的内容仍为string 请问错在哪
{ string str="string";
test(ref str);
textBox1.Text=str;
}public void test(ref string stt)
{
stt="hello,lgg";
}
例如:
string str="12345";
str[0]='2';
是不允许的。还有如果定义
string str1="12345";
string str2="12345";
str1和str2指向的地址是相同的。这和c++中的
char str1[]="12345";
char str2[]="12345";
是不同的。可以把string类型作为特殊来对待。
saucer(思归/MVP) 这不是照样显示了值类型的特点了吗,,一般的引用类型根本不用加ref参数,,只有对于值类型的需要传递他的地址时才用ref,,不是吗??
ReplaceUri(u);
Console.WriteLine(u.ToString());------------------void ReplaceUri(Uri u)
{
u = new Uri("http://127.0.0.1/");
}输出http://www.163.com/
所以引用类型在这里也不会变
加个ref吧
>>>string str2="12345";
>>>str1和str2指向的地址是相同的。str1和str2的地址是不同的
------------------------------这个涉及到了method调用.
在.net里,没有象java的primitive type; C#里所有的type都是一个object.
当一个object被作为参数传递到一个method的时候, 其实在内存某个地方重新创造了这个object的copy:
string str="string";
test(str); <-- 在test里的str所指向的地址其实是内存里另一个地方,而不是原来的那string
textBox1.Text=str; <-- test调用完, test里的那个str也就被释放了,这里的str是原来初始的那个.你可以试试把string改成int,结果一样, 任何类型的参数, 没有ref, 结果都一样,不值会变的
如果改为其他的引用类型,copy的也是地址,而非你所说的copy(你好象说的是内容吧)
当它作为参数时,如果改变它的值,例如:
param1 = param1 + "test"; // 假设原来的值为"TEST"相当于执行了
param1 = new string("TESTtest");当Object用new方法时总会改变其地址.除非用ref/out声明.
你可以用任何一个Object对象试试,比如ArrayList...
所以这样的话,string仍然显示一个引用类型的行为.
不要太拘泥于引用和不引用类型的,关键是在程序中的作用
某些东西,即使他被称为引用类型也不一定传递的是对象的地址,而是拷贝,经常写一些程序你就会发现。
建议如果要保证传递的完全是对象本身,加上ref,不要怕麻烦。
还有struct是值类型。
正是string型变量赋值时总是新建的,所以才有了StringBuilder这个类
youngfox(youngfox)
>>>>>>即使他被称为引用类型也不一定传递的是对象的地址, 而是拷贝,
能不能举个例子,非string类型的
string 对象保留在堆上,而不是堆栈上,当把一个字符串变量赋给另一个字符串时,会得到对内存中同一个字符串的两个引用,然后修改其中一个字符串,会创建一个全新的字符串;
摘自《c#高级编程》
string 对象保留在堆上,而不是堆栈上,当把一个字符串变量赋给另一个字符串时,会得到对内存中同一个字符串的两个引用,然后修改其中一个字符串,会创建一个全新的string对象,而另一个字符串没有改变;
摘自《c#高级编程》你可以试一试!
http://blog.sunmast.com/Sunmast/archive/2004/08/18/857.aspx
但是有个问题
我调一个COM组件时,有个方法要求传个string的引用过去,然后给它赋值,于是我传了string类型变量过,但是无论如何也不得不到值,
我换成StringBuilder以后就可以了.这是为何?请问人指点
比如a = new Array(...如果只是改动该参数(一个对象)的字段,则会有影响,此时加不加ref都是等效的。
比如a[i] = ...============================================================new 之后系统将创建一个同名的private变量,并重新分配内存地址.
所以对会传过的参数(引用类型)不产生作用.但是在new之前对参数所作的任何改动都将反映到
原传入参数
saucer(思归/MVP)我看了一下,,用一个string 付值 于另一个string 是引用地址
但当改变一个string值时,它会在新的地址创建,跟另一个string又没关系了,结果实际的效果不就跟 值类型的一样了吗,达不到引用类型的效果,,为什么要搞的这么复杂,直接 将string设置为 值类型不就好了吗,,
或者说究竟在哪个地方它完完全全的表现了引用类型的所以特点(特别指它的实际效果)
Object
|
--String (引用)
|
--ValueType(引用)
|
--int/char/decimal/...(变成值类型了)
所以说string是引用类型却又有值类型的特点至于微软为什么把string设计成固定大小而又是引用类型
我也觉得挺遗憾的...
要是string就提供StringBuilder的能力该多好
或者就是带了一个char[]的struct,带有n个方法,n个操作符,就像DateTime那样,也不能继承(引用类型的string同样不能继承)
挺郁闷的
等待微软专家指点~
string str1="ssss";
string str2=str1;
这个好象是相当于str2=new string("ssss");
我也不是很清楚,关注中
所以说string是引用类型却又有值类型的特点至于微软为什么把string设计成固定大小而又是引用类型
我也觉得挺遗憾的...
要是string就提供StringBuilder的能力该多好
或者就是带了一个char[]的struct,带有n个方法,n个操作符,就像DateTime那样,也不能继承(引用类型的string同样不能继承)
挺郁闷的
等待微软专家指点~
如果是这个原因的话封装成struct一样可以做到
我觉得这个问题也好办
比如微软这么设计:
struct String
{
public char[] CharArray;
...
}
这样这个结构体只是包含了一个数组指针,复制的时候,也就相当于复制了这个32bit的指针而已,不会存在那个问题吧
所以到处建立拷贝也没事,不管多大的string
不过如果不是使用char[]来实现string的话我的想法就不成立了,嗯...
看起来微软处理这个问题的时候也挺难办的
不过可以确定的是string里面确实还是一个char[]
我没有问题了
谢谢思归 :-)
量, :-)