C# List 作为参数传递的值变化

时间:2022-07-01 10:46:41

一、示例演示

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 作为参数传递的值变化的更多相关文章

  1. HTML5 oninput实时监听输入框值变化的完美方案

    在网页开发中经常会碰到需要动态监听输入框值变化的情况,如果使用 onkeydown.onkeypress.onkeyup 这个几个键盘事件来监测的话,监听不了右键的复制.剪贴和粘贴这些操作,处理组合快 ...

  2. js 实时监听input中值变化

    注意:用到了jquery需要引入jquery.min.js. 需求: 1.每个地方需要分别打分,总分为100; 2.第一个打分总分为40; 3.第二个打分总分为60. 注意:需要判断null.&quo ...

  3. 实时监听输入框值变化:oninput &amp&semi; onpropertychange

    结合 HTML5 标准事件 oninput 和 IE 专属事件 onpropertychange 事件来监听输入框值变化. oninput 是 HTML5 的标准事件,对于检测 textarea, i ...

  4. EF更新,数据库值变化,前台页面并不变化,刷新也不变化,重新运行程序则变化----开发中遇到的问题(已解决)

    首先说一下我遇到这个情况的代码情景,首先上错误代码 UserInfo userInfo = Session["UserInfo"] as UserInfo; ); 这段代码所呈现的 ...

  5. 实时监听输入框值变化的完美方案:oninput &amp&semi; onpropertychange

    实时监听输入框值变化的完美方案:oninput & onpropertychange: 网址:http://www.cnblogs.com/lhb25/archive/2012/11/30/o ...

  6. js监听文本框值变化事件,就oninput &amp&semi; onpropertychange &amp&semi; onkeyup &amp&semi; onchange的区别

    在Web前端项目中实时监听文本框的值变化是非常常见的功能,通常最简单最容易想到的是onkeyup和onchange事件,但是在使用onkeyup来监听键盘事件的时候,监听不到鼠标右键的粘贴.复制的操作 ...

  7. jquery实时监听输入框值变化

    在做web开发时候很多时候都需要即时监听输入框值的变化,以便作出即时动作去引导浏览者增强网站的用户体验感.而采用onchange时间又往往是在输入框失去焦点(onblur)时候触发,有时候并不能满足条 ...

  8. html5 实时监听输入框值变化的完美方案:oninput &amp&semi; onpropertychange

    结合 HTML5 标准事件 oninput 和 IE 专属事件 onpropertychange 事件来监听输入框值变化. H5手机端: <input type="text" ...

  9. 前端组件化Polymer入门教程&lpar;6&rpar;——监听属性值变化

    监听属性值变化 如果需要监听属性值变化可以通过给observer赋值一个回调函数. <say-Hello></say-Hello> <dom-module id=&quo ...

随机推荐

  1. 配置mysql允许远程连接的方法

    默认情况下,mysql只允许本地登录,如果要开启远程连接,则需要修改/etc/mysql/my.conf文件. 一.修改/etc/mysql/my.conf找到bind-address = 127.0 ...

  2. SSIS Send Mail

    在SSIS中Send Mail的方法主要有三种,使用Send Mail Task,使用Script Task和使用存储过程msdb.dbo.sp_send_dbmail. 一,使用Send Mail ...

  3. IDataReader转换成list通用方法

    public static IList<T> ReaderToList<T>(this IDataReader dr) { //DateTime dt = DateTime.N ...

  4. php异步调试和线上调试网站程序的方法

    当碰到一个网站需要不间断运行,但又需要调试该网站的程序错误的时候,该如何办呢?是靠经验一点点猜测,还是直接打印错误信息让其在页面输出? 下面分享一种方法同时满足这两种条件,既方便网站程序错误调试,又不 ...

  5. iOS 多线程编程之Grand Central Dispatch&lpar;GCD&rpar;

    介绍: Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其它的对称多处理系统的系统.这建立在任务并行运行的线程池模式的基础上的. 它 ...

  6. ASP&period;NET中的Excel操作&lpar;OLEDB方式&rpar;

    一:OLEDB方式操作Excel的个人理解 就是把要操作的Excel当作一个数据库,所有对Excel的操作,就变成了对“数据库”的操作.那么这时就需要有一个数据库的连接字符串. 代码如下: connS ...

  7. 初识 BFC、 IFC、GFC、FFC

    首先本文中介绍的 BFC. IFC.GFC.FFC 均为 CSS 中常见问题的解读,如没兴趣,可以绕道了. 然后在介绍这么多的 *FC 之前,我们得了解 一下 Box 和 Formatting Con ...

  8. 详解Linux内核红黑树算法的实现

    转自:https://blog.csdn.net/npy_lp/article/details/7420689 内核源码:linux-2.6.38.8.tar.bz2 关于二叉查找树的概念请参考博文& ...

  9. Discuz常见小问题-如何安装模板,使用模板

    点击应用,获取更多插件 在模板页面中选择需要的类型(需要注册一个账号) 找好一个模板之后,点击安装应用(一般也会有演示) 安装完成之后可以在界面-风格管理中选择安装好的模板,选中新的模板,点击提交即可 ...

  10. Codeforces 608B&period; Hamming Distance Sum 模拟

    B. Hamming Distance Sum time limit per test: 2 seconds memory limit per test:256 megabytes input: st ...