• Break 、Continue 和ReadOnly、Const和Ref和Out params


    Break和Continue区别

    之前对于Break和Continue;ReadOnly和Const;ref和out,params之类的基础东东学习过,但是一直没有仔细去研究到底是怎么一回事儿,最近在开发中用到了,仔细来做个总结:

    1、Break和Continue

        break是跳出整个循环体,不再执行本循环,

        continue是结束单次循环,继续下一次循环

     1  #region Break测试
     2 
     3             Console.WriteLine("========Break========");
     4             int x = 0;
     5             while (x++ < 20)
     6             {
     7                 if (x == 3)
     8                 {
     9                     break;
    10                 }
    11                 Console.WriteLine("{0}
    ",x);
    12             } 
    13             #endregion
    View Code
     1  #region Continue测试
     2             Console.WriteLine("========Continue========");
     3             int k = 0;
     4             while (k++ < 10)
     5             {
     6                 if (k == 3)
     7                 {
     8                     continue;
     9                 }
    10                 Console.WriteLine("{0}
    ",k);
    11             } 
    12             #endregion
    View Code

    2、ReadOnly和Const

      1. const修饰的常量在声明的时候必须初始化;readonly修饰的常量则可以延迟到构造函数初始化  

      2. const修饰的常量在编译期间就被解析,即常量值被替换成初始化的值(编译时常量);readonly修饰的常量则延迟到运行的时候(运行时常量) 

      3. 此外,Const常量既可以声明在类中也可以在函数体内,但是Static ReadOnly常量只能声明在类中。

     1  #region ReadOnly
     2         static readonly int A = B * 10;
     3         static readonly int B = 10;
     4 
     5         const int j = k * 10;
     6         const int k = 10;
     7 
     8         static void Main(string[] args)
     9         {
    10             Console.WriteLine("===Readonly输出的值是:===");
    11             Console.WriteLine("A is {0}.B is {1}", A, B);
    12             Console.WriteLine("===Const输出的值是:===");
    13             Console.WriteLine("j is {0}.k is {1}", j, k);
    14             Console.ReadKey();
    15         }
    16         #endregion
    View Code

    3、ref 和 out,params

    问题的引出:

    现需要通过一个叫Swap的方法交换a,b两个变量的值。交换前a=1,b=2,断言:交换后a=2,b=1

    现编码如下:

     1  1class Program
     2  2    {
     3  3        static void Main(string[] args)
     4  4        {
     5  5            int a = 1;
     6  6            int b = 2;
     7  7            Console.WriteLine("交换前	a={0}	b={1}	",a,b);
     8  8            Swap(a,b);
     9  9            Console.WriteLine("交换后	a={0}	b={1}	",a,b);
    10 10            Console.Read();
    11 11        }
    12 12        //交换a,b两个变量的值
    13 13        private static void Swap(int a,int b)
    14 14        {
    15 15            int temp = a;
    16 16            a = b;
    17 17            b = temp;
    18 18            Console.WriteLine("方法内	a={0}	b={1}	",a,b);
    19 19        }
    20 20    }
    View Code

    运行结果:

                  交换前  a = 1    b = 2

                  方法内  a = 2    b = 1

                  交换后  a = 1    b = 2

    并未达到我们的需求!

    原因分析:int类型为值类型,它存在于线程的堆栈中。当调用Swap(a,b)方法时,相当于把a,b的值(即1,2)拷贝一份,然后在方法内交换这两个值。交换完后,a还是原来的a,b还是原来的b。这就是C#中按值传递的原理,传递的是变量所对应数据的一个拷贝,而非引用。

     

    修改代码如下即可实现我们想要的结果:

     1 class Program
     2  2    {
     3  3        static void Main(string[] args)
     4  4        {
     5  5            int a = 1;
     6  6            int b = 2;
     7  7            Console.WriteLine("交换前	a={0}	b={1}	",a,b);
     8  8            Swap(ref a,ref b);
     9  9            Console.WriteLine("交换后	a={0}	b={1}	",a,b);
    10 10            Console.Read();
    11 11        }
    12 12        //交换a,b两个变量的值
    13 13        private static void Swap(ref int a, ref int b)
    14 14        {
    15 15            int temp = a;
    16 16            a = b;
    17 17            b = temp;
    18 18            Console.WriteLine("方法内	a={0}	b={1}	",a,b);
    19 19        }
    20 20    }
    View Code

    1 关于重载

       原则:有out|ref关键字的方法可以与无out和ref关键字的方法构成重载;但如想在out和ref间重载,编译器将提示:不能定义仅在ref和out的上的方法重载

    2 关于调用前初始值

       原则:ref作为参数的函数在调用前,实参必须赋初始值。否则编译器将提示:使用了未赋值的局部变量;

                 out作为参数的函数在调用前,实参可以不赋初始值。

    3 关于在函数内,引入的参数初始值问题

       原则:在被调用函数内,out引入的参数在返回前至少赋值一次,否则编译器将提示:使用了未赋值的out参数;

                 在被调用函数内,ref引入的参数在返回前不必为其赋初值

    总结: C#中的ref和out提供了值类型按引用进行传递的解决方案,当然引用类型也可以用ref和out修饰,但这样已经失去了意义。因为引用数据类型本来就是传递的引用本身而非值的拷贝。ref和    out关键字将告诉编译器,现在传递的是参数的地址而不是参数本身,这和引用类型默认的传递方式是一样的。同时,编译器不允许out和ref之间构成重载,又充分说明out和ref的区别仅是编译    器角度的,他们生成的IL代码是一样的。有人或许疑问,和我刚开始学习的时候一样的疑惑:值类型在托管堆中不会分配内存,为什么可以按地址进行传递呢?值类型虽然活在线程的堆栈          中,它本身代表的就是数据本身(而区别于引用数据类型本身不代表数据而是指向一个内存引用),但是值类型也有它自己的地址,即指针,现在用ref和out修饰后,传递的就是这个指针,所以可    以实现修改后a,b的值真正的交换。这就是ref和out给我们带来的好处。

  • 相关阅读:
    天气预报 Web 服务
    安装IE8在控制面板里面删除之后进不去桌面,提示找不到IESetting.dll 解决办法(解决IE8卸载不了的问题,返回IE7 ,返回IE6),从IE8回到IE7的方法.
    提供股票的Web Sservices 接口
    vc中操作Xml使用CMarkup类
    不要埋怨空降兵了
    图像分割与描述
    [非常感人] 我还能再救一个!
    向汶川地震中死难者致哀
    关于dotNet加密工具
    不注册使用 .NET Reactor
  • 原文地址:https://www.cnblogs.com/QQ931697811/p/3951502.html
Copyright © 2020-2023  润新知