• 修改引用的值 与 修改引用(通过方法)


     阅读代码: 

    View Code
     1 class Program
    2 {
    3 static void Main()
    4 {
    5 Person p1 = new Person { Name = "Andy" };
    6 Person p2 = p1;
    7
    8 ModifyReferenceValue(p1);
    9 ModifyReference(p1);
    10 p1 = new Person { Name = "David"};
    11 }
    12
    13 static void ModifyReferenceValue(Person p3)
    14 {
    15 p3.Name = "Bill";
    16 }
    17
    18 static void ModifyReference(Person p4)
    19 {
    20 p4 = new Person { Name = "Carol" };
    21 }
    22 }

     第5行:在栈上分配一个变量p1,p1的类型为Person;在堆上分配一个Person实例,该实例的Name为Andy;将P1 指向Andy实例。 

    第6行:在栈上分配一个变量p2,p2的类型为Person;将p1 赋值给p2;这时候p1,p2 都指向Andy实例。 

    第8行:调用方法ModifyReferenceValue;在栈上分配一个变量P3,P3的类型为Person;复制引用,将P1赋值给P3;此时P1,P2,P3都指向Andy实例;修改P3变量的值,实际上是修改P3指向的Andy实例,将Andy实例的Name修改为Bill;由于P1,P2,P3的Name都是Bill;方法调用结束,释放P3在栈上的内存。 

    第9行:调用方法ModifyReference;在栈上分配一个变量P4,P4的类型为Person;复制引用,将P1赋值给P4;此时P1,P2,P4都指向Bill实例;修改P4,使它指向在堆上刚刚创建的Carol实例;此时,P4指向Carol实例,P1,P2仍然指向Bill实例;方法调用结束;释放P4在栈上的内存;这时候没有引用指向Carol实例,GC会在合适的时机,回收堆上的Carol实例; 

    第10行:修改P1,使它指向在堆上刚刚创建的David实例;此时P1指向David实例,P2仍然指向Bill实例。 


     总结:在调用方法传递参数的过程中: 

    1、如果参数是值类型,由于值类型是“整体拷贝”,对值类型的修改只在当前方法范围内有效,不会影响到外部。调用方法结束后,在栈上弹出,不会产生副作用。 

    2、如果参数是引用类型并且修改引用的值,由于引用类型是“复制引用”,修改引用的值,将产生副作用。与当前引用 指向实例相同的引用都会变化。 

    3、如果参数是引用类型并且修改引用使之指向其他的实例,不会产生副作用。 

    因此,需要注意 修改引用的值 与 修改引用的区别。 

  • 相关阅读:
    Content-Type: multipart/form-data; boundary=
    -ErrorAction SilentlyContinue
    計量文件夾大小
    使用tesseract識別簡單的圖形碼
    适用于演示场景的修改网页内容
    分页展示与标题行
    查询当前脚本运行环境
    选项菜单
    tomcat创建虚拟目录存储图片
    springmvc记录(页面回显、url模板映射、自定义参数绑定、全局异常处理、文件上传、拦截器、hibernate validation数据校验、静态资源映射)
  • 原文地址:https://www.cnblogs.com/nzbbody/p/2317177.html
Copyright © 2020-2023  润新知