原则:尽可能控制对数据的修改,如果可以预测某个数据不会或不应该被改变,就要对其控制,而不要期望使用这个数据的调用者不会改变其值。

如果参数在使用过程中被意外修改,将会带来不可预知的结果,而且这种错误很难被检查到,所以我们在设计方法参数的时候,要充分考虑传递引用类型参数或者引用方式传递引用类型参数可能带来的后果。

如果一个数据在传递过程中不能被改变,就要在构建这个对象的时候就使其值(字段或属性)不被改变。

一、对于简单的参数的控制

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#中数组作为参数传递的问题的更多相关文章

  1. js中数组作为参数传递的定义

    下面的函数实现了一个我们想要的最基本的图片预加载效果 function preloadimages(arr){    var newimages=[]    var arr=(typeof arr!= ...

  2. C++中数组作为形参进行传递(转)

    有两种传递方法,一种是function(int a[]); 另一种是function(int *a) 这两种两种方法在函数中对数组参数的修改都会影响到实参本身的值! 对于第一种,根据之前所学,形参是实 ...

  3. php中数组操作函数

    一.数组操作的基本函数数组的键名和值array_values($arr);  获得数组的值array_keys($arr);  获得数组的键名array_flip($arr);  数组中的值与键名互换 ...

  4. java 中函数的参数传递详细介绍

    java中函数的参数传递 总结: 1.将对象(对象的引用)作为参数传递时传递的是引用(相当于指针).也就是说函数内对参数所做的修改会影响原来的对象.  2.当将基本类型或基本类型的包装集作为参数传递时 ...

  5. 数组类型参数传递问题:$.ajax传递数组的traditional参数传递必须true

    数组类型参数传递: 若一个请求中包含多个值,如:(test.action?tid=1&tid=2&tid=3),参数都是同一个,只是指定多个值,这样请求时后台会发生解析错误,应先使用 ...

  6. C++中数组作为形参的方法

    转载:https://blog.csdn.net/qq_33374294/article/details/90769668 原链接:https://www.cnblogs.com/abella/p/1 ...

  7. JavaScript中数组操作常用方法

    JavaScript中数组操作常用方法 1.检测数组 1)检测对象是否为数组,使用instanceof 操作符 if(value instanceof Array) { //对数组执行某些操作 } 2 ...

  8. jq中数组应用的错误

    js中数组可以这样使用: <ul id="ul"> <li value="1">s</li> <li>f< ...

  9. C++程序设计(关于函数中数组传递的一点心得)

    题目: 10个学生考完期末考试评卷完成后,老师需要划出及格线,要求如下: (1) 及格线是10的倍数: (2) 保证至少有60%的学生及格: (3) 如果所有的学生都高于60分,则及格线为60分:   ...

随机推荐

  1. CentOS6上安装Flash Player

    Linux CentOS6服务器中的某个需要远程操作的项目需要使用到Adobe Flash Player组件,直接通过YUM方式安装不了,于是通过强大的搜索,还是可以解决到安装方法的,通过重新加载安装 ...

  2. java使用POI写Excel文件

    参考地址:http://www.cnblogs.com/xwdreamer/archive/2011/07/20/2296975.html 1 jar包 网上下载 2 源代码 package zjr. ...

  3. Python与Go选择排序

    #!/usr/bin/env python # -*- coding: utf-8 -*- # 选择排序 # 时间复杂度O(n^2) def selection_sort(array): length ...

  4. java 蓝桥杯算法提高 _1区间k大数查询

    import java.util.Scanner; public class _1区间K大数查询 { public static void main(String[] args) { Scanner ...

  5. coding创建项目

    在本地,使用git 需要创建一个pom.xml文件,就可以导入到工作空间了! 在需要项目工作空间里,依次使用git命令执行 mkdir test  //创建文件夹,项目名称cd test   //切换 ...

  6. jquery下的提交,点击按钮没反应,post方法不执行 JSON方式在FORM表单下不起作用

    jquery下的提交,点击按钮没反应,post方法不执行 JSON方式在FORM表单下不起作用

  7. linux系统软件版本升级

    在安装完软件之后,在同一层目录生成一个符号链接,并把当前软件的目录映射到这个链接上,后面的操作都只通过这个链接去做,以后升级版本的时候,把最新的软件目录映射到这个链接上就可以了. 如我刚装的apach ...

  8. 修改字段注释modify

    alter table test1 modify 字段名 类型 comment '修改后的字段注释'; ALTER TABLE tc_activity_miaosha MODIFY `validity ...

  9. Memcached在Windows下的配置和使用(转)

    出处:http://www.cnblogs.com/sunniest/p/4154209.html Memcached学习笔记---- 安装和配置 首先,下载Memcached相关文件. 打开控制台, ...

  10. Spring框架总结(八)

    二.Cglib代理名词理解: Cglib代理,也叫做子类代理.利用继承关系实现被代理类的功能扩展.缺点:      (1)JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口.  ...