关于C#string的类型

本文解析了C#中字符串作为引用类型的特殊行为,并通过实例对比了引用类型与值类型的差异。

提问:

class Class1
{
    static void StrChange(string str)
    {
      str = "hellow";
    }

    static void Main()
    {
      string str = "123";//申明一个字符串
      StrChange(str);//调用方法
      Console.WriteLine(str);//输出字符串
    }
}

输出的结果是 "123"
string 到底是值类型还是引用类型?
如果是值类型,结果倒还说的过去.但是我记得string 是引用类型啊...难道是我记错了??
如果是引用类型的话.输出的结果应该是: "hellow"
请问这是为什么啊?? 大家帮忙解释一下..谢谢

提问者: 贺爱平 - 菜鸟二级


问题补充:class Program
{
//引用类型
class SomeRef
{
public int x;
}

//值类型
struct SomeVal
{
public int x;
}

private static void ChangeRef(SomeRef r)
{
r.x = 555;
}

private static void ChangeVal(SomeVal v)
{
v.x = 5556;
}


static void Main(string[] args)
{
SomeRef r1 = new SomeRef();//分配在托管堆上

SomeVal v1 = new SomeVal();
r1.x = 5;//解析指针

v1.x = 5;
ChangeRef(r1);

ChangeVal(v1);

Console.WriteLine(r1.x);
Console.WriteLine(v1.x);

}

}

 

回答:

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才会不相同。

请注意,这个机制很特殊,它既不是普通的对象那样,也和按值传递不同,按值传递是将整个值传了一个拷贝进去,因此无论怎么修改也两不干扰。

写的尽可能通俗易懂了,尽可能白话了,应该理解了吧?

5天前  回答者: Coki - 菜鸟二级

补充:没搞懂你问题补充是为了说明什么…… SomeRef会被初始化在堆上,SomeVal会被初始化在栈上,ChangeRef时,形参r会获得和r1相同的地址引用,ChangeVal时,形参v会获得v1的一个完整的拷贝,然后再被放在栈的一个新区域去。所以,r1被传进ChangeRef之后,r的改变即为r1的改变,而v1被传递进ChangeVal之后,其实传递的是一个完整的包含值的拷贝,此时v与v1已经没有任何关系。所以之后r1被修改了,而v1没有改变。正好印证了我的以上说法。
-- Coki 1天前 
应该说是和string是有差别的。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值