C#中数组作为参数传递的问题
原则:尽可能控制对数据的修改,如果可以预测某个数据不会或不应该被改变,就要对其控制,而不要期望使用这个数据的调用者不会改变其值。
如果参数在使用过程中被意外修改,将会带来不可预知的结果,而且这种错误很难被检查到,所以我们在设计方法参数的时候,要充分考虑传递引用类型参数或者引用方式传递引用类型参数可能带来的后果。
如果一个数据在传递过程中不能被改变,就要在构建这个对象的时候就使其值(字段或属性)不被改变。
一、对于简单的参数的控制
1、值类型参数传递
这种情况因为传递的是参数的副本,不影响原始值,不需要控制。
2、引用类型参数传递
a、由值类型组成的数据结构
需要将字段设置为只读,属性只有get。赋值只能通过构造方法进行。
b、包含引用类型字段的数据结构
这种情况是递归的,需要保证字段为readonly,属性为get的同时,引用类型字段所使用类型也满足该要求。
public class SuperClass
{
private readonly int _no;
private readonly SubClass _tag; public int NO
{
get{ return _no;}
} public SubClass Tag
{
get{ retirn _tag;}
} public SuperClass(int no,SubClass tag)
{
_no=no;
_tag=tag;
}
} public class SubClass
{
private readonly int _field; public int Field
{
get{ return _field;}
} public SubClass(int field)
{
_field=field;
}
}
二、对于复杂引用类型参数传递的控制
所谓复杂,是参数是数组或集合类型,或者参数包含这些类型数据,这种情况下上面的方法不能保证参数数据不被修改,因为即使对象为只读的,但是对象中的数组或集合字段(属性)还是可以修改的。
1、集合参数(包含集合字段的引用参数也一样)
.net 4.5以前版本可以使用不包含修改集合元素方法的接口来代替具体集合类型。例如使用IEnumerable<T>接口代替List<T>。4.5版本可以直接使用IReadOnlyCollection接口或实现该接口的集合类型。
2、数组参数
没有好的办法保护数组类型参数不被修改,所以尽量避免使用数组类型作为方法参数,除非用到可选参数时候。
三、理解上面的东西需要区分清楚一下概念的区别
1、值类型和引用类型的区别
2、值传递和引用传递(ref和out)的区别
3、传递引用类型参数和引用传递(ref和out)引用类型参数的区别 [这一点最容易混淆]
区别在于使用该参数过程中为该引用新建了对象的情况下,前者不影响原始值,后者影响原始值,示例:
void FunA(MyClass a)
{
a=new MyClass("A");
}
void FunB(ref MyClass a)
{
a=new MyClass("B");
}
void Test()
{
MyClass a=new MyClass("A");
FunA(a);
Print(a); //a还是原始的对象 TEST
FunB(ref a);
Print(a); //a变为新对象 B
}
记住一条原则:
值类型传递的是值的副本,引用类型传递的是对象引用,所以值参数的修改不影响原始值,引用类型的修改影响原始值;值传递的参数构建不影响原始值,引用传递(ref和out)影响原始值。
C#中数组作为参数传递的问题的更多相关文章
- js中数组作为参数传递的定义
下面的函数实现了一个我们想要的最基本的图片预加载效果 function preloadimages(arr){ var newimages=[] var arr=(typeof arr!= ...
- C++中数组作为形参进行传递(转)
有两种传递方法,一种是function(int a[]); 另一种是function(int *a) 这两种两种方法在函数中对数组参数的修改都会影响到实参本身的值! 对于第一种,根据之前所学,形参是实 ...
- php中数组操作函数
一.数组操作的基本函数数组的键名和值array_values($arr); 获得数组的值array_keys($arr); 获得数组的键名array_flip($arr); 数组中的值与键名互换 ...
- java 中函数的参数传递详细介绍
java中函数的参数传递 总结: 1.将对象(对象的引用)作为参数传递时传递的是引用(相当于指针).也就是说函数内对参数所做的修改会影响原来的对象. 2.当将基本类型或基本类型的包装集作为参数传递时 ...
- 数组类型参数传递问题:$.ajax传递数组的traditional参数传递必须true
数组类型参数传递: 若一个请求中包含多个值,如:(test.action?tid=1&tid=2&tid=3),参数都是同一个,只是指定多个值,这样请求时后台会发生解析错误,应先使用 ...
- C++中数组作为形参的方法
转载:https://blog.csdn.net/qq_33374294/article/details/90769668 原链接:https://www.cnblogs.com/abella/p/1 ...
- JavaScript中数组操作常用方法
JavaScript中数组操作常用方法 1.检测数组 1)检测对象是否为数组,使用instanceof 操作符 if(value instanceof Array) { //对数组执行某些操作 } 2 ...
- jq中数组应用的错误
js中数组可以这样使用: <ul id="ul"> <li value="1">s</li> <li>f< ...
- C++程序设计(关于函数中数组传递的一点心得)
题目: 10个学生考完期末考试评卷完成后,老师需要划出及格线,要求如下: (1) 及格线是10的倍数: (2) 保证至少有60%的学生及格: (3) 如果所有的学生都高于60分,则及格线为60分: ...
随机推荐
- ffmpeg源码分析四:transcode_step函数 (转4)
原帖地址:http://blog.csdn.net/austinblog/article/details/25099979 该函数的主要功能是一步完整的转换工作,下面看看源代码: static int ...
- JAVA压缩 解压缩zip 并解决linux下中文乱码
1. [代码][Java]代码 1:再压缩前,要设置linux模式, 需要使用第三方ant-1.6.5.jar 如果是文件目录,则ZipEntry zipEntry=new ZipEntry(b ...
- Python_安装官方whl包和tar.gz包
Windows环境: 安装whl包:pip install wheel -> pip install **.whl 安装tar.gz包:cd到解压后路径,python setup. ...
- 免费视频教学:30天精通iPho…
原文地址:免费视频教学:30天精通iPhone手机编程(全)作者:苹果iphone软件编程 土豆连接http://www.tudou.com/playlist/id12638619.html
- 一条跨库更新数据的sql
UPDATE [db1].[dbo].[R_ResAndBook] SET SectionID=TT2.newsecidFROM [SmartCampus].[dbo].[R_ResAndBo ...
- 关于StringUtils类isEmpty、isNotEmpty、isBlank、isNotBlank针对null、空字符串和空白字符(如空格、制表符)的区别
isEmpty | null | 空字符串("")|空白字符(空格.制表符)| | isEmpty | true | true | false | | isNotEmpty | f ...
- MongoDB 数组操作
$push:向文档数组中添加元素,如果没有该数组,则自动添加数组.db.users.insert({"name":"zhang"})db.users.updat ...
- Python3 模块与包
一.模块介绍 什么是模块? 常见的场景:一个模块就是一个包含了一组功能的Python文件,比如spam.py,模块名为spam,可以通过import spam使用. 在Python中,模块的使用方式都 ...
- SQL 数据库 学习 006 如何设置一个用户名和密码
我的电脑系统: Windows 10 64位 使用的SQL Server软件: SQL Server 2014 Express 先启动 SQL Server 2014 Management Studi ...
- 关于HBase的memstoreFlushSize。
memstoreFlushSize是什么呢? memstoreFlushSize为HRegion上设定的一个阈值,当MemStore的大小超过这个阈值时,将会发起flush请求. 它的计算首先是由Ta ...