文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何分析CLR Via的方法及参数

2023-06-17 22:06

关注

如何分析CLR Via的方法及参数,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

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

1、CLR Via之out

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

static void Main(string[] args)            {                string name = string.Empty;                GetStr(out name); //调用时加out                Console.WriteLine(name);            }            private static void GetStr(out string name) //方法参数定义时的out            {                name = "oec2003";           }

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

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

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

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

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

2、CLR Via之ref

private static void GetStr(out string name)         {            name = "oec2003";        }        private static void GetStr(string name)        {            name = "oec2003";        }

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

static void Main(string[] args)         {              string name;              GetStr(ref name); //如果name没有赋值不能通过编译              Console.WriteLine(name);          }          private static void GetStr(ref string name)           {              name = "oec2003";         }          static void Main(string[] args)          {              string name="oec2003";              GetStr(ref name);              Console.WriteLine(name);//返回:hello oc2003         }          private static void GetStr(ref string name)           {              name = "hello " + name;         }

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

static void Main(string[] args)          {              string name="oec2003";              GetStr(ref name);              Console.WriteLine(name);//在方法中没有操作,仍然返回oec2003          }          private static void GetStr(ref string name)           {                ......       }

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

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

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

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

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

static void Main(string[] args)         {             Console.WriteLine(Add(1,2,3,4));         }         public static int Add(params int[] num)         {             int sum = 0;             foreach (int i in num)             {                sum += i;            }            return sum;        }

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

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

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

//使用的弱类型参数            private void OperateCollection<T>(IEnumerable<T> collection)            {                         }            //使用的强类型参数            private void OperateCollection<T>(List<T> collection)            {               ......         }

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

看完上述内容,你们掌握如何分析CLR Via的方法及参数的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯