分析CLR Via的方法参数相关

开发 后端
本文通过4各方面对CLR Via进行讲解,其中它们有可变数量的参数、方法的参数类型等。希望能给你带来帮助。

本文通过4各方面对CLR Via进行讲解,其中它们有可变数量的参数、方法的参数类型等。希望能给你带来帮助。

《CLR Via C#》这本书以前就粗略看过两遍,但一直都没能深入理解,而且很多内容也忘记了,现在准备重新看一遍,并将看过的部分写出来,因为写的过程也是一个加深理解的过程。

本系列算是学习的一个记录吧,也可以方便以后自己查阅,如果对大家还有些帮助的话,我就很高兴了。书我是选择性的看的,所以顺序和书中的顺序可能不一样。

通常我们在使用方法的时候,方法的参数是按值传递的,如果传递的参数是引用类型的对象,是将引用对象的地址传给方法。如果传递的是值类型实例,传递给方法的是该实例的一个副本。CLR Via允许使用在方法中按引用来传递参数,C#中使用out和ref关键字来体现。下面就来介绍out和ref的使用。

1、CLR Via之out

(1)使用out时在方法的参数定义和方法的调用时都要用out关键字,如下:

  1. static void Main(string[] args)  
  2.           {  
  3.               string name = string.Empty;  
  4.               GetStr(out name); //调用时加out  
  5.               Console.WriteLine(name);  
  6.           }  
  7.           private static void GetStr(out string name) //方法参数定义时的out  
  8.           {  
  9.               name = "oec2003";  
  10.          }  

(2)如果一个方法有out修饰的参数,在方法结束前必须给给参数赋值,否则不能通过编译,代码如下:    

  1. static void Main(string[] args)  
  2.       {  
  3.           string name = "oec2003";  
  4.           GetStr(out name);  
  5.           Console.WriteLine(name);  
  6.       }  
  7.       private static void GetStr(out string name)  
  8.       {  
  9.           //没有给name赋值,编译时会出现“控制离开当前方法之前必须对 out 
  10. 参数“name”赋值”异常  
  11.       }  

(3)在调用有out参数的方法时,没有必要给out参数赋初始值,因为赋的值不会传递到方法的内部,如果在方法的内部要强行使用out参数会有编译错误。代码看下面,通常我们需要在一个方法中返回多个值的时候就可以使用out参数。和out参数一样,使用ref时在方法的参数定义和方法的调用时都要用ref关键字。和out不同的是ref参数的值可以传入方法内进行操作。

  1. static void Main(string[] args)  
  2.      {  
  3.          string name = "oec2003"; //给out参数name赋初始值oec2003  
  4.          GetStr(out name);  
  5.          Console.WriteLine(name);  
  6.      }  
  7.      private static void GetStr(out string name)   
  8.      {  
  9.          name = "hello" + name; //name在调用前虽赋值为oec2003 ,  
  10.                                     //但此处会报错“使用了未赋值的 out 参数name”  
  11.      }   

(4)如果两个方法的参数个数和类型都相同,区别只是其中一个为out参数,那么这两个方法是可以进行重载的,下面的代码可以正常运行。     

2、CLR Via之ref

  1. private static void GetStr(out string name)   
  2.       {  
  3.           name = "oec2003";  
  4.       }  
  5.       private static void GetStr(string name)  
  6.       {  
  7.           name = "oec2003";  
  8.       }  

(1)如果调用方法前,ref参数没有赋初始值,不能通过编译,看如下代码:

  1. static void Main(string[] args)  
  2.        {  
  3.             string name;  
  4.             GetStr(ref name); //如果name没有赋值不能通过编译  
  5.             Console.WriteLine(name);  
  6.         }  
  7.         private static void GetStr(ref string name)   
  8.         {  
  9.             name = "oec2003";  
  10.        }  
  11.         static void Main(string[] args)  
  12.         {  
  13.             string name="oec2003";  
  14.             GetStr(ref name);  
  15.             Console.WriteLine(name);//返回:hello oc2003  
  16.        }  
  17.         private static void GetStr(ref string name)   
  18.         {  
  19.             name = "hello " + name;  
  20.        } 

(2) 因为ref在传入方法时会有初始值,所以在方法的内部可以不对ref参数进行任何的操作,那样ref参数的值不会改变。

  1. static void Main(string[] args)  
  2.         {  
  3.             string name="oec2003";  
  4.             GetStr(ref name);  
  5.             Console.WriteLine(name);//在方法中没有操作,仍然返回oec2003  
  6.         }  
  7.         private static void GetStr(ref string name)   
  8.         {  
  9.               ......
  10.        }  

(3)同out参数一样,如果两个方法的参数个数和类型都一样,仅有的区别只是其中之一的参数为ref参数,两个可以进行重载。

对于CLR Via来说,关键字out和关键字ref是等价的,就是说无论使用的out还是ref,都会生成相同的IL代码,正因为如此,如果两个方法的差异仅仅是out和ref的差异,那么这两个方法是不能进行重载的,如下代码:

  1. //下面代码编译会报“不能定义仅在 ref 和 out 上有差别的重载方法”异常  
  2.          private static void GetStr(ref string name)   
  3.          {  
  4.              name = "oec2003";  
  5.          }  
  6.          private static void GetStr(out string name)  
  7.          {  
  8.              name = "oec2003";  
  9.          }  
  10.    

3、CLR Via之可变数量的参数

有些时候如果一个方法的参数数量可以根据用户的需要而进行变动,那将会带来很大的方便。像String类型的Concat、Format等方法就提供了可变参数。可以变参数在C#中使用params来定义,如下面代码:

  1. static void Main(string[] args)  
  2.        {  
  3.            Console.WriteLine(Add(1,2,3,4));  
  4.        }  
  5.        public static int Add(params int[] num)  
  6.        {  
  7.            int sum = 0;  
  8.            foreach (int i in num)  
  9.            {  
  10.               sum += i;  
  11.           }  
  12.           return sum;  
  13.       }  

使用可变参数非常简单,需要注意的是可变参数的类型一定要是数组类型。可变参数虽然很好用,但是接受可变参数的方法在调用时会导致一些性能损失,以为数组对象必须分配在堆上,数组的内存最终需要GC来回收。为了避免这种性能的损耗,我们在写方法的时候可以多定义几个没有params关键字的方法的重载,这样只有在很特殊的情况下才会使用有params关键字的方法。

4、CLR Via之方法的参数类型

声明方法参数类型时,应尽可能只用弱的类型,例如如果要编写一个操作一组数据项的方法,***使用接口(如Ienumerable)来定义方法参数的类型,而不要使用一些强的数据类型如List或是一些强的接口类型(如Ilist或Icollection),如下:  

  1. //使用的弱类型参数  
  2.           private void OperateCollection<T>(IEnumerable<T> collection)  
  3.           {   
  4.             
  5.           }  
  6.           //使用的强类型参数  
  7.           private void OperateCollection<T>(List<T> collection)  
  8.           {  
  9.      ......
  10.          }  

此处所指的强类型和弱类型,可以理解为类型的层次,如果说父类的层次高于子类,那么层次越高就类型越弱。Iemumerable接口直接在 System.Collections 命名空间下,是其他一些集合类和接口(如Icollection IList List等)的基类,所以定义参数为IEnumerable 类型的,凡是继承了IEnumerable 的类型的参数都能够传入方法,大大提高了灵活性。

以上就是对CLR Via的简单介绍。

【编辑推荐】

  1. 浅析基于SQL2005的CLR存储过程
  2. 分析与对比CLR Via C#静态构造函数的性能
  3. 为你解疑:CLR是什么?
  4. linq to sql多表查询浅析
  5. linq to sql多表基础描述
责任编辑:阡陌 来源: CSDN
相关推荐

2009-09-17 18:56:22

CLR Via C#

2009-09-18 09:02:45

CLR Via C#

2009-10-23 11:31:05

CLR Via C#调

2009-10-22 19:11:25

CLR Via C#教

2016-10-08 22:33:54

相关分析数据

2009-10-22 18:41:49

CLR VIA C#教

2010-02-25 13:54:48

WCF安全参数

2009-10-22 17:18:20

CLR触发器

2009-09-18 13:47:17

CLR类库

2009-10-23 09:12:23

CLR与操作系统关系

2009-07-24 10:42:28

CLR线程池

2023-03-17 08:00:34

OpenCVCvType错误

2021-10-26 00:00:53

数据分析指标

2010-01-18 17:15:20

VB.NET参数类型不

2010-03-29 16:31:48

2010-04-16 11:39:56

Oracle存储过程

2011-02-23 10:21:18

ProFTPd参数

2010-04-26 19:15:10

Oracle参数文件

2014-01-07 15:23:15

HadoopYARN

2022-11-14 14:36:59

数据集Python自相关
点赞
收藏

51CTO技术栈公众号