C# List 作为参数传递的值变化
一、示例演示
namespace TestConsole
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(""); List<string> list1 = new List<string>();
Test1(list1);
Console.WriteLine(" list1:" + list1.Count()); // 总数量为 1 Console.WriteLine("");
Console.WriteLine("---- 亮瞎眼的分割线 ----");
Console.WriteLine(""); List<string> list2 = new List<string>();
Test2(list2);
Console.WriteLine(" list2:" + list2.Count()); // 总数量仍为 0 Console.WriteLine("");
} static void Test1(List<string> list)
{
list.Add("");
Console.WriteLine(" Test1():" + list.Count()); // 总数量为 1
} static void Test2(List<string> list)
{
List<string> list2 = new List<string>();
list2.Add(""); list = list2;
Console.WriteLine(" Test2():" + list.Count()); // 总数量为 1
}
}
可以发现:
经过 Test1后,list 的元素数量由 0 变为 1 了,
经过 Test2后,list 的元素数量还是0。
二、解说
1.list类型是引用类型
2.引用本身是类似于一个“保存地址的值变量”
所以从方法外部传入引用到方法里,那么其实引用本身是复制了一份副本来给方法里使用的,只是说这个复制的引用副本和之前的引用的内容(也就是所指向的对象内存地址)是一样的,所以通过引用操作对象的数据时,可以看到2个引用都操作的同一个对象;但如果你是修改了引用副本本身的值内容(将该引用指向了一个新的对象的内存地址),那么是不会影响到之前方法外的那个引用的,所以修改后会发现2个引用所指向的对象不同了
而如果对象引用参数前加上了ref,那么方法参数所传递的不再是引用的副本,而是引用的地址了(即通过引用的地址找到引用,再读出引用里保存的内存地址值,再根据则个地址值去找到真正要操作的对象),所以如果此时你再修改这个引用的值时,会根据引用的地址找到方法外的那个引用,然后修改其内容,所以会发现方法外的引用也会指向新的对象了
3这里有三段代码
你可以看看,体会一下:
(1)
List<string> list=new List<string>();
ModifyList(list);
Console.WriteLine(list.Count) private void ModifyList(List<string> list)
{
// 这里的list其实已经是一个引用副本了,但是所指向的内存地址仍然是原本方法外面的对象的,所以后面用该引用的Add方法所操作的,仍然是原本方法外面的对象的内存数据
list.Add("");
list.Add("");
list.Add("");
}
(2)
List<string> list=new List<string>();
ModifyList(list);
Console.WriteLine(list.Count) private void ModifyList(List<string> list)
{
list = new List<string>(); // 这里其实已经将引用指向了新的内存地址,所以后续的Add操作是在操作新对象的内存数据,而原来方法外的对象其实是没有受到影响的
list.Add("");
list.Add("");
list.Add("");
}
(3)
List<string> list=new List<string>();
List<string> copy = list; // 复制一个引用
ModifyList(ref list);
Console.WriteLine(copy.Count) // 复制的这个引用仍然指向原来最早的那个List
Console.WriteLine(list.Count) // list这个引用已经在ModifyList方法里被修改了,指向的是在ModifyList方法里新new出来的对象了 private void ModifyList(ref List<string> list)
{
list = new List<string>(); // 因为有ref,所以这里其实已经将方法外原本的那个引用也指向了新的内存地址,所以后续的Add操作是在操作新对象的内存数据,并且方法外原本的那个引用也指向了这个新的对象
list.Add("");
list.Add("");
list.Add("");
}
参考:
http://www.cftea.com/c/2013/01/5724.asp
http://bbs.csdn.net/topics/390600826
C# List 作为参数传递的值变化的更多相关文章
- HTML5 oninput实时监听输入框值变化的完美方案
在网页开发中经常会碰到需要动态监听输入框值变化的情况,如果使用 onkeydown.onkeypress.onkeyup 这个几个键盘事件来监测的话,监听不了右键的复制.剪贴和粘贴这些操作,处理组合快 ...
- js 实时监听input中值变化
注意:用到了jquery需要引入jquery.min.js. 需求: 1.每个地方需要分别打分,总分为100; 2.第一个打分总分为40; 3.第二个打分总分为60. 注意:需要判断null.&quo ...
- 实时监听输入框值变化:oninput & onpropertychange
结合 HTML5 标准事件 oninput 和 IE 专属事件 onpropertychange 事件来监听输入框值变化. oninput 是 HTML5 的标准事件,对于检测 textarea, i ...
- EF更新,数据库值变化,前台页面并不变化,刷新也不变化,重新运行程序则变化----开发中遇到的问题(已解决)
首先说一下我遇到这个情况的代码情景,首先上错误代码 UserInfo userInfo = Session["UserInfo"] as UserInfo; ); 这段代码所呈现的 ...
- 实时监听输入框值变化的完美方案:oninput & onpropertychange
实时监听输入框值变化的完美方案:oninput & onpropertychange: 网址:http://www.cnblogs.com/lhb25/archive/2012/11/30/o ...
- js监听文本框值变化事件,就oninput & onpropertychange & onkeyup & onchange的区别
在Web前端项目中实时监听文本框的值变化是非常常见的功能,通常最简单最容易想到的是onkeyup和onchange事件,但是在使用onkeyup来监听键盘事件的时候,监听不到鼠标右键的粘贴.复制的操作 ...
- jquery实时监听输入框值变化
在做web开发时候很多时候都需要即时监听输入框值的变化,以便作出即时动作去引导浏览者增强网站的用户体验感.而采用onchange时间又往往是在输入框失去焦点(onblur)时候触发,有时候并不能满足条 ...
- html5 实时监听输入框值变化的完美方案:oninput & onpropertychange
结合 HTML5 标准事件 oninput 和 IE 专属事件 onpropertychange 事件来监听输入框值变化. H5手机端: <input type="text" ...
- 前端组件化Polymer入门教程(6)——监听属性值变化
监听属性值变化 如果需要监听属性值变化可以通过给observer赋值一个回调函数. <say-Hello></say-Hello> <dom-module id=&quo ...
随机推荐
- Chrome DevTools: Color tricks in the Elements Panel
shift + click to change the color format Tip one The Colour Platters are customeised for you .they s ...
- redis安全问题【原】
前提 假设redis安装在 IP 地址为 192.168.0.123 的linux服务器 . 我的本机Win10操作系统 IP地址为 192.168.0.45 , 有一套java客户端代码可调用lin ...
- tomcat下的Cookie特殊符号问题
案例:在项目中通过Cookie方式临时存放检索条件,不小心在Cookie值中使用了特殊符号"@",导致在服务器端无法正确解析Cookie值.之所以说"不小心", ...
- html取消回车刷新提交
<form class="weui-search-bar__form" onsubmit="return false;"> <form cla ...
- 新浪某站CRLF Injection导致的安全问题
CRLF攻击的一篇科普:新浪某站CRLF Injection导致的安全问题(转) 转:https://www.leavesongs.com/PENETRATION/Sina-CRLF-Injectio ...
- (5)top k大的数目
一.问题 在一个很长的数组中,求出top k大小的数目 二.办法 用优先队列 时间复杂度O(nlog(k)),应该是最差的情况下是这个 三.Code package algorithm; import ...
- Django之CRM项目Day6-公私户转换问题解决 班主任功能
1.解决公户转私户的问题 数据库中加锁: begin; 开始事务 select * from user where id=1 for update; 加锁 commit; 结束事务 dja ...
- call apply bind 区别?
call apply bind 区别? 例:定义一个计算器,没绑定bind的为公共计算器,call可以调用,绑定bind的为私人计算器,别人调用不了, //ps:用bind绑定的call强制作借用不好 ...
- java 通过域名获取ip
1. java InetAddress[] allByName = InetAddress.getAllByName("www.baidu.com"); 2. nslookup
- 第27月第24天 git pull fetch
1. 在进行 pull 操作的同时,其实就是 fetch+merge 的一个过程.我们从 remote 分支中拉取新的更新,然后再合并到本地分支中去. 如果 remote 分支超前于本地分支,并且本地 ...