C# 深入理解值类型和引用类型
估计以前大家都知道:值类型赋值时是赋值一份,引用类型是传递的地址吧。但是你真的觉得自己了解了这些么?看一下这篇文章,我想你会有收获的。
例子出处:http://blog.csdn.net/u010533180/article/details/53064257#reply
1.案例
主函数
static void Main( string[ ] args )
{
Console.WriteLine("1.返回值在try中,int类型");
Console.WriteLine( Test( ) );
Console.WriteLine( "2.返回值在最后,int类型" );
Console.WriteLine( Test2( ) );
Console.WriteLine( "3.返回值在try中,string类型" );
Console.WriteLine( Test3( ) );
Console.WriteLine( "4.返回值在最后,string类型" );
Console.WriteLine( Test4( ) );
Console.ReadLine( );
}
实例方法
public static int Test( )
{
int i = 0;
try
{
return i;
}
finally
{
i = 2;
}
}
public static int Test2( )
{
int num = 0;
int num2 ;
try
{
num2 = num;
}
finally
{
num = 2;
}
return num2;
}
public static string Test3( )
{
string i = "";
try
{
return i;
}
finally
{
i = "有";
}
}
public static string Test4( )
{
string str = "";
string str2;
try
{
str2 = str;
}
finally
{
str = "有";
}
return str2;
}
在看下面之前,你可以先自己猜想一下,4个方法分别返回什么内容。想好之后,再继续向下看:
2.分析
答案:
是不是有点没想到?如果想到了,那下面的不用看了。。如果没想到,那就听听我的分析吧。
注:finally是在try块执行完后,一定要执行的。这个结构主要用于异常捕捉,不知道的萌新可以自行百度一下
第一个test方法
public static int Test( )
{
int i = 0;
try
{
return i;
}
finally
{
i = 2;
}
}
第一个其实应该不难,返回的是0这个值,并不是i的引用。。虽然变量也是指向一个内存空间,但在编译时,给的是里面的值。
第二个test方法
public static int Test2( )
{
int num = 0;
int num2 ;
try
{
num2 = num;
}
finally
{
num = 2;
}
return num2;
}
第二个要高级一点点,但其实只要知道值类型赋值是复制了一份就没问题了。这里,try块是给num2赋值的0,然后下面的代码都和num2没关系,num2是要返回的值,他在得到值后就没有被调用过了,所以也是0;下面的要绕一点点了
第三个test方法
public static string Test3( )
{
string i = "";
try
{
return i;
}
finally
{
i = "有";
}
}
这里,retrun的不是i这个变量,是返回的i里面指向的内存地址。地址的引用类型里可以认为是值类型的里面的“值”,不同的是:值类型是存的值,引用类型存的是地址。
后面的finaly和返回的“地址”已经没有关系了,所以返回的是”“
第四个test方法
public static string Test4( )
{
string str = "";
string str2;
try
{
str2 = str;
}
finally
{
str = "有";
}
return str2;
}
这个要复杂一点点,但如果有了第三个例子的思路,其实也不难了。str2在赋值时,赋值是的是”“的引用,不是链接到str上面,所以在str里的引用变了之后,不会影响到str2里。
3.总结
其实这些东西,平时不注意也不会太影响。。只是让大家留意一下。。因为代码多了之后,提示bug的地方和真正导致BUG的地方有时距离非常远,有可能就是类似今天说的东西导致的