C# 深入理解值类型和引用类型

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hjkl950217/article/details/60383412

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的地方有时距离非常远,有可能就是类似今天说的东西导致的

猜你喜欢

转载自blog.csdn.net/hjkl950217/article/details/60383412