string,你到底是谁?

很久以前,成龙上演了一部《我是谁》,现在string也遭遇了相同的问题.无论在JAVA中还是.NET中它永远都是一种“明星”气质,考虑它总是要从特殊性的角度考虑,它属于基本数据类型,也是基本数据类型中唯一的引用类型。

现在我们知道,C#我们一直在使用字符串string关键字的映射实际上指向.NET 基类System.String。也就是说string 是 .NET Framework 中的 System.String 的别名,只是说string是C#里面的类而已。System.String是一个功能非常强大且用途非常广泛的基类,但它不是.NET中惟一与字符串相关的类,该类专门用于存储字符串,允许对字符串进行许多操作。

string 对象称为不可变的(只读),因为一旦创建了该对象,就不能修改该对象的值。看来似乎修改了 string 对象的方法实际上是返回一个包含修改内容的新 string 对象。
这句话初听起来似乎有些不可思议,大家也许马上会想到字符串的连接操作,我们不也可以改变字符串吗?看下面这段代码:
string name = “1234”; …….1
name = name + “5678”; …….2
Console.WriteLine(name); …….3
看起来我们似乎已经把name的值从“1234”改为了“12345678”。事实是这样的吗?实际上并没有改变。在第1行代码中创建了一个string对象它的值是“1234”,name指向了它在内存中的地址;第2行代码中创建了一个新的string对象它的值是“12345678”,name指向了新的内存地址。这时在堆中其实存在着两个字符串对象,尽管我们只引用了它们中的一个,但是字符串“1234”仍然在内存中驻留。
那么如果多次修改一个字符串,请使用System.Text.StringBuilder, 因为它是专门为这种情况设计的应用StringBuilder来创立字符串能显著的减少内存分配.

class Program
{
static void Main(string[] args)
{
string s1 = “”;
StringBuilder s2 = new StringBuilder();
DateTime dt1 = DateTime.Now;
for (int i = 0; i < 10000; i++)
{
s1 = s1 + i.ToString();
}
DateTime dt2 = DateTime.Now;
for (int i = 0; i < 10000; i++)
{
s2.Append(i.ToString());
}
DateTime dt3 = DateTime.Now;
Console.WriteLine(dt2-dt1);
Console.WriteLine(dt3-dt2);
}
}

从这里可以看出,当出现多字符串连接时,尽量使用StringBuilder。它简单而且直接,当然,一般情况下觉察不到这二者效率的差异,但如果你要对某个字符串进行大量的添加操作,那么StringBuilder类所耗费的时间和String类简直不是一个数量级的。

string 对象是引用类型,不是值类型。您也许马上会做以下实验:
class Program
{
static void Main(string[] args)
{
string myname = “abc”;
ChangeValue(myname);
Console.WriteLine(name);

          }
         static void ChangeValue(string name)
         {
               name = "efg";
         }
}

结果:
abc
如果按照引用类型,传递的应该是地址,修改了name的值,那么myname的值应该也要做相应的修改,结果应该是”efg”,但事实与之相反。
现在string是引用类型是可以确定的:

  1. string继承自object,而不是System.ValueType(Int32这样的则是继承于System.ValueType) (大家可以做下实验,通过GetType()的BaseType属性)
  2. string本质上是个char[],而Array是引用类型,并且初始化时也是在托管堆分配内存的
    那么上面的事实又怎么解释呢?
    应该说name和myname是同一地址,你改了myname,本应该name的值也随着改变的,但这样就等于立刻创建了个新字符串,并把name指向新的。这时候myname还指向原来的。所以没变。string的所有所谓“改变”都创建了新的实例。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值