学习 - 2008-3-16 9:25:00
下面代码的输出结果是什么?
class Program
{
static void Main(string[] args)
{
string b;
b = "old";
Func1(ref b);
Console.WriteLine(b); int c;
c = 3;
Func1(ref c);
Console.WriteLine( c);
}
public static void Func1(ref string a)
{
a = "new";
}
public static void Func1(ref int a)
{
a = 6;
}
}
答案:
new
6
题目2:下面代码的输出结果是什么?
class Program
{
static void Main(string[] args)
{
string b;
b = "old";
Func1( b);
Console.WriteLine(b);
int c;
c = 3;
Func1( c);
Console.WriteLine( c);
}
public static void Func1( string a)
{
a = "new";
}
public static void Func1( int a)
{
a = 6;
}
}
答案:
old
3
解释:两端代码的关键区别点在于---那个ref。
可以看到,在题目1中,由于ref的存在,变量b和c的值被改变了。可是在题目2中,变量b和c的值没有发生改变,这主要是因为c#中不同类型的数据它们的存储方式的不同。
题目1中:
string b中存储的是"old"的地址,而由于使用了ref,a中得到的是b的地址,这样在函数Func1中对a修改的时候,实际上是首先得到以a中存储的数据作为地址的那片空间里的数据的值,也就是b里面的内容,再找把b里面的内容作为地址的那片空间,将里面对数据给改了。于是"old"被改成了"new",图示如下
题目2中:
string b中存储的还是"old"的地址,但是我们没有使用ref,a中得到的就是b的内容,因此这个时候a和b里面存储的都是"old"的地址。
这样在函数Func1中对a修改的时候,电脑就会去修改以a中存储的数据作为地址的那片空间里的数据的值,也就是说,电脑想去把"old"改成"new"。
可是就在这个时候,C#或者说.NET的某种检查机制发现,"new"这片空间同时被a和b指着,于是电脑说“小a啊,你不能这个样子啊,你这么一改,那我们家小b的利益就得不到保障了啊,这是不行的啊,小伙子八荣八耻学得不够啊!”
a说:“关你屁事,只要我boss下次读取的时候,我给出个new就可以了”。
电脑想了想,说:“那好吧,我另外给你块地方,把你的new存起来得了。”
于是,电脑做了一个"new string“的动作,另外开了块地方,把new保存起来,然后把a的内容改成了那块新空间的地址。这样,当我们再次访问b的时候,电脑就把以b的内容作为地址的空间的东西给输出了,显然,那是没有经过改变的"old",图示如下
对于c的操作也是类似,但是由于这里使用了重载的函数Func1,为了避免多个重名局部变量a带来的麻烦,就不解释对整数c的操作过程