本文摘自PHP中文网,作者黄舟,侵删。
C#.net 提供的4个关键字,in,out,ref,paras开发中会经常用到,那么它们如何使用呢? 又有什么区别?1 in
in只用在委托和接口中;
例子:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
分析原因,ForEach的参数是委托函数:
1 |
|
委托是泛型的,类型T前加了一个关键字in,因为带有关键字in,所以T obj是不能被修改的。
尝试测试:
1 |
|
结果每个元素都乘以2,变为2,8,12。可知,可以修改对象的属性。
2 out
out 关键字用法注意:
1)带有out的形参,在函数定义时,return前必须给函数赋一个值。
2)调用函数时,带有out的参数不必赋一个初始值。
3)out形参传值是通过引用(by reference)
out使用场景:
在函数返回多个值时,通常用out 返回其中一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
C#.net中有一类TryParse函数,便是out的另一个重要应用。若感兴趣,请见:透过Parse和TryParse:Try-Parse和Tester-Doer模式
3 ref
ref关键字用于改变参数传递,将by value修改为by reference传值,原来是by reference传递的,加上ref还是不加ref,效果是一样的。
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
如何修改对象model中的属性a,将其变为12呢?
1 2 3 4 5 6 |
|
因此,ref关键词使用总结:
ref的话,用于处理值变量,如基本类型、结构等,它们不需要被new出来,传值依照的是值拷贝。
1)ref 后的变量,如果是值类型(value type),那么加上ref后变为按照 by reference传值;
2)ref 后的变量,如果是引用类型(reference type),那么加上ref与不加没有任何区别;
3)ref后的变量,使用前必须赋值
4)ref后的变量不能是引用类型的属性
以上是基本的分析,在使用中就够了,如果想更深入的分析这个问题,请继续。
4 深入探讨out ref
主要分析out ref 到底有何用,不用他们会有什么影响。
1) C#中有一类方法,名字叫作Try…,如Int.TryParse,它返回一个bool值,尝试解析一个字符串,如果成功解析为整数,则返回true,得到的整数作为第二个out的int被传出。
见分析文章
异常设计准则
透过Parse和TryParse:Try-Parse和Tester-Doer模式
从文章中看出,相比没有out参数的次方法Parse,如果解析字符串失败,则会抛出一个参数错误的异常。
用Try…方法写出来的代码比try…catch写出来的要简洁,于是这也变成了out参数使用的一个常用场景。
2) Java和C#比较
在Java里,HashMap
1 2 3 4 |
|
但val == null,既可能是该map里尚未有键为该key的键值对,也可能是已经有该键值对了但是其值为null。
要区分两者,HashMap提供了containsKey()方法。所以正确的写法是这样的:
1 2 3 4 |
|
containsKey()跟get()的内部操作几乎是一模一样的,都要做一次hash查找,只是返回了查找结果的不同部分而已。也就是说按照这种“正确写法”来写的话,访问一次HashMap就有双倍开销了。杯具!
C#有许多这种细节设计比Java更贴心。看C#用out关键词如何改进这个问题。
System.Collections.Generic.Dictionary
1 2 3 4 5 6 7 |
|
利用这个方法,上面的Java代码对应的C#版就可以写成:
1 2 3 4 |
|
这就把ContainsKey与Item[Key]的语义结合了起来,把一次hash查找能找到的信息一口气都返回出来,从源头上避免了“两次查找”的冗余操作,有利于程序的性能。
C#.net中提供了一个关键字 params,以前都不知道有这个关键字,有一次,同事看到我的几版重载函数后,淡定地和我说了一句,哥呀,你可以用params,后来查了查,现在经常用习惯了,这不刚才又把之前写的几版都拿掉了,又用params重构了下。
5 Paras
那么,我就把params的用处,我经历的这个过程说一下。
5.1 问题的需求
在客户端,客户经常会变动查询的字段,前几天还是根据4个关键字段去服务器查询几个模型呢,今天,又想加1个查询字段。
根据4个关键字段的查询方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
调用的getPlansWithCondition方法为
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
问题来了,当查询再新加1个字段时,你难道还再重载一个版本吗?
5.2 应用params
1 |
|
当C#提供了params后,当然不用,直接将getMPartPlansWithCondition改写为如下
1 2 3 4 5 6 7 8 9 10 11 |
|
以后随意添加查询字段,只要修改下这个函数就行了,不用增删重载版本!!!
客户端调用,直接加一个字段就行
1 |
|
5.3 总结
queryFun(params object[] objs),带有这个参数的函数,只需要一个版本,这样解决了因为个数不一致而导致的多个重载版本,
在客户端调用时,将属性参数一一列数即可。
以上就是.NET框架- in ,out, ref , paras使用的代码总结的详细内容!
相关阅读 >>
更多相关阅读请进入《.NET框架》频道 >>
C#高级编程(第11版) C# 7 & .NET Core 2.0(.NET开发经典名著)
作者:[美]克里斯琴·内格尔(Christian Nagel)著。出版时间:2019年3月。