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("1");
            Console.WriteLine(" Test1():" + list.Count()); // 总数量为 1
        }

        static void Test2(List<string> list)
        {
            List<string> list2 = new List<string>();
            list2.Add("1");

            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("1");
    list.Add("2");
    list.Add("3");
}

(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("1");
    list.Add("2");
    list.Add("3");
}

(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("1");
    list.Add("2");
    list.Add("3");
}

参考:

http://www.cftea.com/c/2013/01/5724.asp

http://bbs.csdn.net/topics/390600826

时间: 2024-11-07 10:24:26

C# List 作为参数传递的值变化的相关文章

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

首先说一下我遇到这个情况的代码情景,首先上错误代码 UserInfo userInfo = Session["UserInfo"] as UserInfo; var attentionTopicInfos = userInfo.TopicInfos.Where(t => t.TopicId > 0); 这段代码所呈现的问题正如题目,数据库值变化,前台页面并不变化,刷新也不变化,重新运行程序则变化. 断点调试----看到无论如何更新,查出来的attentionTopicInf

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

在 Web 开发中经常会碰到需要动态监听输入框值变化的情况,如果使用 onkeydown.onkeypress.onkeyup 这个几个键盘事件来监测的话,监听不了右键的复制.剪贴和粘贴这些操作,处理组合快捷键也很麻烦.因此这篇文章向大家介绍一种完美的解决方案:结合 HTML5 标准事件 oninput 和 IE 专属事件 onpropertychange 事件来监听输入框值变化. oninput 是 HTML5 的标准事件,对于检测 textarea, input:text, input:pa

js/jquery 实时监听输入框值变化的完美方案:oninput &amp; onpropertychange

本文转载于 http://blog.163.com/lgh_2002/blog/static/44017526201341511112874/ Jquery绑定事件(bind和live的区别) js/jquery 实时监听输入框值变化的完美方案:oninput & onpropertychange js/jquery 实时监听输入框值变化的完美方案:oninput & onpropertychange 2013-05-15 11:01:12|  分类: jquery/javascrip |

thinkphp3.2开发排错一例——当__APP__的值变化后,需要删除缓存~runtime.php文件

经过是这样的: 在根目录下建立了一个文件夹weixin,之前通过www.domain.com/weixin访问,后来想改成二级域名weixin.domain.com访问,但通过U方法生成的路径中仍含有weixin/,通过输出__APP__的值发现也带weixin/,删除缓存~runtime.php文件后解决问题 thinkphp3.2开发排错一例--当__APP__的值变化后,需要删除缓存~runtime.php文件,布布扣,bubuko.com

js 实时监听input中值变化

js 实时监听input中值变化 分类: Javascript2014-05-11 11:13 849人阅读 评论(0) 收藏 举报 [html] view plaincopyprint? <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>RunJS

【转载】函数参数传递(值传递,指针传递)

C语言值传递 地址传递 : 1.值传递 eg: 1     void Exchg1(int x, int y)   2     {   3          int tmp;   4          tmp = x;   5          x = y;   6          y = tmp;   7          printf("x = %d, y = %d\n", x, y);   8     }   9     main()  10     {  11        

关于实时监听输入框的值变化

实时监听文本框值变化是非常常见的功能,通常最简单的办法就是用keyup,keydown来实现,但是这种方法有两个问题,一个是当直接复制粘贴的时候没法监听到事件,另外一个问题是在移动端,使用删除键删除输入时候也无法监听到! 解决办法: 1.使用onchange事件 onchange事件是文本框内容改变并失去焦点的时候才触发. 2.比较完美的解决办法:oninput和onproper oninput 是 HTML5 的标准事件,对于检测 textarea, input:text, input:pas

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

在网页开发中经常会碰到需要动态监听输入框值变化的情况,如果使用 onkeydown.onkeypress.onkeyup 这个几个键盘事件来监测的话,监听不了右键的复制.剪贴和粘贴这些操作,处理组合快捷键也很麻烦.因此这篇文章向大家介绍一种完美的解决方案:结合html5标准事件 oninput 和 IE 专属事件 onpropertychange 事件来监听输入框值变化.,对于检测 textarea, input:text, input:password 和 input:search 这几个元素

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

结合 HTML5 标准事件 oninput 和 IE 专属事件 onpropertychange 事件来监听输入框值变化. H5手机端: <input type="text" placeholder="请输入金额" value="" oninput="only_number(this)"> //输入框,限金额 function only_number(obj) { //先把非数字的都替换掉,除了数字和. obj.v