class Class1
{
static void StrChange(string str)
{
str = "hellow";
}
static void Main()
{
string str = "123";//申明一个字符串
StrChange(str);//调用方法
Console.WriteLine(str);//输出字符串
}
}
输出的结果是 "123"
string 到底是值类型还是引用类型?
如果是值类型,结果倒还说的过去.但是我记得string 是引用类型啊...难道是我记错了??
如果是引用类型的话.输出的结果应该是: "hellow"
请问这是为什么啊?? 大家帮忙解释一下..谢谢
我的理解是这样的:
StrChange是传值调用,传进去的是一个地址,相当于一个指针,这个指针是str的一个副本,在函数中,这个副本分配了一个内存空间,指向了“hellow”, 但是str的对应的内存空间并没有改变。如果在StrChange中改变str的值,可以这样声明:
static void StrChange(ref string str)
{
str = "hellow";
}
这样使用:
StrChange(ref str);//调用方法
ref的意思是把str的值传入到函数中,又分配了一块内存空间。
不知解释清楚了没
string是内置引用类型,但参数的引用类型与这个不是同一概念,加个ref则结果不同。
请看
http://www.cnblogs.com/downmoon/archive/2007/12/29/1019301.html
string 是特殊的引用类型,为特例
1.string 是引用类型,它是一个横定量,不可变的,还有个字符串驻留~~~
至于你的那个啊:
可以这样理解:
string str = "123";//str指向 字符串对性"123" 的地址(注意"123"就是一个对象,赋值操作只是对其引用)
StrChange(str);//传参,将str对象的指针拷贝作为参数传递
static void StrChange(string str)
{
str = "hellow"; //在这里只是str的拷贝复制,因此对原来的str没有影响
}
////////////////////////////////
你可以试一下下面,就可以得到结果“hellow”,对引用类型ref传参
引用类型的传参其实也是传拷贝,只是传的是引用地址的拷贝,而非对象本身~~
static void StrChange(ref string str)
{
str = "hellow";
}
//ps:其实string实际上可以说除去字符串驻留之外和平常的引用类型的行为时一模一样的。只是string 因为可以将如:"hellow" 当成一个对象,我们永远只能对其引用,string的本身就是它的值的啊!!!你怎么去修改它呢??再说string实在clr的元类型,其的值是恒定的~~~
2.补充问题里面:结果应该是 555 5
结构体就不说了,类中的值类型成员实例在内存中也是放在堆中,她的操作也是引用的行为:)
ps:这里是你必须知道的。net,你可以看一下,他说得很清楚~~呵呵
http://www.cnblogs.com/anytao/mytag.aspx?tag=《你必须知道的.NET》&page=1
在面向对象里面,理想的情况下“一切都是对象”, 但为了方便(比如不用new就可以使用),Java和C#都定义了int、bool、string...它们不是对象,它们叫做“简单类型”。 简单类型都是值传递的。string还有另外的特别之处,有兴趣可去我的博客看看, 刚写完, ^_^。
建议你读一下,《你必须知道的.net》中的8.3节-- 如此特殊:大话string
String是引用类型,这是不用质疑的,但是String引用的对象非常特殊。
C#为了减少字符串的内存占用,采取了这样的策略,相同的字符串使用相同的内存空间,比如string a = "123"和string b = "123",虽然是两个string,但它们指向同一个内存地址。
请注意string由此带来的特殊性,假如此刻给a重新赋值:a = "456",原先那个内存地址中存放的依旧是"123"这是无法修改的,所以只能修改a的内存指向。
现在我们来看方法传值,普通的Object o传递进方法Me(Object o),真正的过程是,先新建一个新的变量o1(假设是这个名字),然后把o的引用地址复制给o1,现在o和o1引用相同的对象。现在在方法中修改o1.Name = "新名字",修改的是被o和o1共同引用的对象,因此o.Name自然也会变成新名字。
再看String,string s = "旧名字",传递进Me(string s),真正的过程是,先新建一个新的变量s1,然后把s的引用地址复制给s1,现在s和s1引用相同的字符串内存地址。方法中修改s1="新名字",由于原先的内存中的"旧名字"无法修改成"新名字",所以就需要新建一个内存空间存"新名字",然后将新的地址给s1,所以这时s和s1已经引用的不是同一个地址了!所以s和s1才会不相同。
请注意,这个机制很特殊,它既不是普通的对象那样,也和按值传递不同,按值传递是将整个值传了一个拷贝进去,因此无论怎么修改也两不干扰。
写的尽可能通俗易懂了,尽可能白话了,应该理解了吧?
你直接写成 Console.WriteLine(StrChange(str)); 尝试下。