C#.net 提供的4个关键字,in,out,ref,paras开发中会经常用到,那么它们如何使用呢? 又有什么区别?
1 in
in只用在委托和接口中;
例子:
//测试模型 class Model { public int a { get; set; } public Model(int a) { this.a = a; } }//创建3个实例List<Model> modelList= new List<Model>() { new Model(1), new Model(4), new Model(6) };//调用foreach接口,试着操作3个实例,赋值为nullmodelList.ForEach(e=>e=null); //查看结果://modelList的取值不变。
分析原因,ForEach的参数是委托函数:
//ForEach方法:public void ForEach(Action<T> action);//委托声明:public delegate void Action<in T>(T obj);
委托是泛型的,类型T前加了一个关键字in,因为带有关键字in,所以T obj是不能被修改的。
尝试测试:
//修改元素e的属性amodelList.ForEach(e=>{e.a*=2;});
结果每个元素都乘以2,变为2,8,12。可知,可以修改对象的属性。
2 out
out 关键字用法注意:
1)带有out的形参,在函数定义时,return前必须给函数赋一个值。
2)调用函数时,带有out的参数不必赋一个初始值。
3)out形参传值是通过引用(by reference)
out使用场景:
在函数返回多个值时,通常用out 返回其中一个
public bool Operation(out Model updateMod) { updateMode = new Model(5); try{ // my operation ... // return true; } catch{ //写入日志 return false; } }//使用Model um; //未初始化bool rtnMsg = Operation(out um); //如果初始化,传值通过reference//分析://返回um,如果rntMsg为ture,则um按照预想逻辑被赋值, //如果rntMsg为false 则um未按照预想逻辑被赋值。
C#.net中有一类TryParse函数,便是out的另一个重要应用。若感兴趣,请见:透过Parse和TryParse:Try-Parse和Tester-Doer模式
3 ref
ref关键字用于改变参数传递,将by value修改为by reference传值,原来是by reference传递的,加上ref还是不加ref,效果是一样的。
例如:
public void reviseModel(int a) { a = 12; } Model model = new Model(10); //调用reviseModelreviseModel(model.a); //model.a仍然=10;by-valuereviseMode(ref model.a); //编译不过,提示ref后的参数不归类与变量int a; reviseMode(ref a); //如果不给变量a赋一个初始值, //编译器也是提示:调用前未被赋值的错误 //因此赋值int a= model.a; //变量a初始值为10;reviseMode(ref a); //修改变量a=12;但是model.a的值仍然为10
如何修改对象model中的属性a,将其变为12呢?
//直接将参数设为Model对象,则函数调用时,传值通过by referencepublic void reviseModel(Model md) { md.a = 12; } reviseModel(model );//传值通过by reference
因此,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
// HashMap<K, V> map; // K key; V val = map.get(key);if (val != null) { // ...}
但val == null,既可能是该map里尚未有键为该key的键值对,也可能是已经有该键值对了但是其值为null。
要区分两者,HashMap提供了containsKey()方法。所以正确的写法是这样的:
// HashMap<K, V> map; // K key;if (map.containsKey(key)) { V val = map.get(key); // ...}
containsKey()跟get()的内部操作几乎是一模一样的,都要做一次hash查找,只是返回了查找结果的不同部分而已。也就是说按照这种“正确写法”来写的话,访问一次HashMap就有双倍开销了。杯具!
C#有许多这种细节设计比Java更贴心。看C#用out关键词如何改进这个问题。
System.Collections.Generic.Dictionary
TryGetValue: Dictionary(TKey, TValue).TryGetValue Method (TKey, TValue) (System.Collections.Generic)public bool TryGetValue( TKey key, out TValue value )ParameterskeyType: TKey The key of the value to get. valueType: TValue
利用这个方法,上面的Java代码对应的C#版就可以写成:
// Dictionary<TKey, TValue> dict; // TKey key; TValue val;if (dict.TryGetValue(key, out val)) { // ...}
这就把ContainsKey与Item[Key]的语义结合了起来,把一次hash查找能找到的信息一口气都返回出来,从源头上避免了“两次查找”的冗余操作,有利于程序的性能。
C#.net中提供了一个关键字 params,以前都不知道有这个关键字,有一次,同事看到我的几版重载函数后,淡定地和我说了一句,哥呀,你可以用params,后来查了查,现在经常用习惯了,这不刚才又把之前写的几版都拿掉了,又用params重构了下。
5 Paras
那么,我就把params的用处,我经历的这个过程说一下。
5.1 问题的需求
在客户端,客户经常会变动查询的字段,前几天还是根据4个关键字段去服务器查询几个模型呢,今天,又想加1个查询字段。
根据4个关键字段的查询方法:
public void GetPlansByInputControl(string planState, string contactno,DatePair dp) { string planStat = ""; switch (planState) { case "...": planStat = "..."; break; case "...": planStat = "..."; break; } plans = getPlansWithCondition(Convert.ToDateTime(dp.startValue), Convert.ToDateTime(dp.endValue), planStat, contactno); }
调用的getPlansWithCondition方法为
private List<MPartPlan> getMPartPlansWithCondition(DateTime dateTime, DateTime dateEndTime, string planStat, string contactNo) { var conditions = new CslSqlBaseSingleTable(); conditions.AddCondition("RequireStartDate", dateTime, DataCompareType.GreaterOrEqual); conditions.AddCondition("RequireStartDate", dateEndTime, DataCompareType.LessOrEqual); conditions.AddCondition("OrderCode", contactNo, DataCompareType.Equal); if (!string.IsNullOrEmpty(planStat)) { conditions.AddCondition("PlanState", planStat, DataCompareType.Equal); } return _cslMPartPlan.QueryListInSingleTable(typeof(MPartPlan), conditions); } }
问题来了,当查询再新加1个字段时,你难道还再重载一个版本吗?
5.2 应用params
private List<MPartPlan> getMPartPlansWithCondition(DateTime dateTime, DateTime dateEndTime, string planStat, string contactNo,string newField);
当C#提供了params后,当然不用,直接将getMPartPlansWithCondition改写为如下
private List<MPartPlan> getMPartPlansWithCondition(params object[] queryConditions); { queryConditions[0] queryConditions[1] queryConditions[2] queryConditions[3] queryConditions[4] //放到字典中dict sqlQuery(dict); }
以后随意添加查询字段,只要修改下这个函数就行了,不用增删重载版本!!!
客户端调用,直接加一个字段就行
_bsl.GetPlansByInputControl(field1, field2,field3,field4,field5);
5.3 总结
queryFun(params object[] objs),带有这个参数的函数,只需要一个版本,这样解决了因为个数不一致而导致的多个重载版本,
在客户端调用时,将属性参数一一列数即可。
C#.net 提供的4个关键字,in,out,ref,paras开发中会经常用到,那么它们如何使用呢? 又有什么区别?
以上就是C# in ,out, ref , paras用处的详细介绍的内容,更多相关内容请关注PHP中文网(www.php.cn)!

C#.NET生态系统提供了丰富的框架和库,帮助开发者高效构建应用。1.ASP.NETCore用于构建高性能Web应用,2.EntityFrameworkCore用于数据库操作。通过理解这些工具的使用和最佳实践,开发者可以提高应用的质量和性能。

如何将C#.NET应用部署到Azure或AWS?答案是使用AzureAppService和AWSElasticBeanstalk。1.在Azure上,使用AzureAppService和AzurePipelines自动化部署。2.在AWS上,使用AmazonElasticBeanstalk和AWSLambda实现部署和无服务器计算。

C#和.NET的结合为开发者提供了强大的编程环境。1)C#支持多态性和异步编程,2).NET提供跨平台能力和并发处理机制,这使得它们在桌面、Web和移动应用开发中广泛应用。

.NETFramework是一个软件框架,C#是一种编程语言。1..NETFramework提供库和服务,支持桌面、Web和移动应用开发。2.C#设计用于.NETFramework,支持现代编程功能。3..NETFramework通过CLR管理代码执行,C#代码编译成IL后由CLR运行。4.使用.NETFramework可快速开发应用,C#提供如LINQ的高级功能。5.常见错误包括类型转换和异步编程死锁,调试需用VisualStudio工具。

C#是一种由微软开发的现代、面向对象的编程语言,.NET是微软提供的开发框架。C#结合了C 的性能和Java的简洁性,适用于构建各种应用程序。.NET框架支持多种语言,提供垃圾回收机制,简化内存管理。

C#和.NET运行时紧密合作,赋予开发者高效、强大且跨平台的开发能力。1)C#是一种类型安全且面向对象的编程语言,旨在与.NET框架无缝集成。2).NET运行时管理C#代码的执行,提供垃圾回收、类型安全等服务,确保高效和跨平台运行。

要开始C#.NET开发,你需要:1.了解C#的基础知识和.NET框架的核心概念;2.掌握变量、数据类型、控制结构、函数和类的基本概念;3.学习C#的高级特性,如LINQ和异步编程;4.熟悉常见错误的调试技巧和性能优化方法。通过这些步骤,你可以逐步深入C#.NET的世界,并编写高效的应用程序。

C#和.NET的关系是密不可分的,但它们不是一回事。C#是一门编程语言,而.NET是一个开发平台。C#用于编写代码,编译成.NET的中间语言(IL),由.NET运行时(CLR)执行。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

禅工作室 13.0.1
功能强大的PHP集成开发环境