资讯专栏INFORMATION COLUMN

C#中对引用类型的误解

itvincent / 1562人阅读

摘要:举例分析这里从我们常用的两个购物平台淘宝京东来举例说明引用地址传递。总结引用类型传递的是对象的引用,是将引用地址以副本的方式进行传递。

C#中对引用类型的误解

值类型和引用类型作为两个非常基础而且很重要的概念,一般我们都是在最开始的时候学的,你听到的可能是这样的:值类型传递的是具体的值(副本),引用类型传递的是引用,对于前者大家都不会有什么疑惑,但是在引用类型上就可能会进入一些误区。

概念插入:

值类型:值类型传递的是数据的副本,也就是将整个数据进行Copy然后赋值给另一个变量。

引用类型:传递的是对象的地址/路径(一般都会叫做引用),在对象的赋值过程中实际上是把目标对象的地址以副本的形式给了接收的对象。

实例说明

如下我们新建了一个Student类,定义了一个变量student1,然后定义了一个变量student2并将student1赋值给了它,紧接着创建了student3并将student3赋值给了student1。

输出结果:1

class Program
{
    static void Main(string[] args)
    {
        //step1
        Student student1 = new Student() { StudentId = 1 };
        Student student2 = student1;
        Student student3 = new Student() { StudentId = 3 };
        //step2
        student1 = student3;
        Console.WriteLine(student2.StudentId.ToString());
        Console.ReadKey();
    }
}
public class Student
{
    public int StudentId { get; set; }
}

Step1的操作如下图所示:

在图中的右侧我们使用矩形代替两个通过new关键字创建的对象,并为其标识了两个虚拟的ID,在左侧我们定义了三个变量,如图的圆角矩形所示,这三个变量不是真正意义上的对象,只是对象的一个所在地址而已,也就是我们通过这个变量就可以找到一个特定的地址。其中student1变量持有的ID(内存地址)为1001,student2也是1001,student3为1002。这里需要注意的是student1的1001和student2的1001虽然都是指向的1001,但是这两个1001都只是对象地址的一个副本,也就是说student1的1001和student2的1001并不是同一个,只是被Copy了而已(可以理解为这个地址是以值类型的方式进行传递的)。

这里要注意的是变量student2和student1是没有关系的,它们只和右侧的1001有关系,只是它们地址的值是相等的。

new关键字:

创建特定对象的实例并返回其引用地址(只是返回了地址的一个副本,而不是真正的对象)

When the object is created, the memory is allocated on the managed heap, and the variable holds only a reference to the location of the object.(来源于官方文档:https://docs.microsoft.com/en... )

译:创建对象后,内存会在托管堆上进行分配,并且变量只保留对对象位置的引用。

Step2的操作如下图所示:

在Step2的代码中我们将student3的变量赋值给了student1,那么这段代码执行的是将student3对应的ID(引用地址)以副本的方式给了student1。

//step2
student1 = student3;
Console.WriteLine(student2.StudentId.ToString());
Console.ReadKey();

如果你对引用传递理解有有偏差的话你可能会认为student2的地址也会变成1002,也就是student2.StudentId变成了3。这样理解是不正确的,我们刚才说过了虽然它们的引用地址是都是1001,但是这个地址也是通过副本进行传递的。也就是说当student1的地址发生改变并不会影响student2的地址。

再述:

当右侧对象中的值发生改变时,通过左侧变量来获取拿到的就是改变后的值,而当左侧变量值的改变时并不会影响右侧对象值的。左侧变量值的改变只是对应的地址发生了改变而不是对象的值发生了改变。

举例分析

这里从我们常用的两个购物平台淘宝、京东来举例说明引用地址传递。

右侧有两个对象分别是淘宝和京东,左侧我们定义了三个变量来保存这个对象的地址(和上边的例子是一样的)

如下图,我们将valA变量存放的地址改成了www.jd.com ,我们只是改变了变量存放的地址而并没有改变valA之前所对应的对象的值。

总结

引用类型传递的是对象的引用,是将引用地址以副本的方式进行传递。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/110536.html

相关文章

  • JavaScript参数传递方式

    这几天遇到js参数传递方式的问题,深切探究一番,将所得结果总结于此 常见的几种传递方式 传值调用(call by value) 在传值调用中实际参数被求值,其值被绑定到函数中对应的变量上(通常是把值复制到新内存区域)。在函数返回后调用者作用域里的曾传给函数的任何东西都不会变。 传引用调用(call by reference) 在传引用调用求值中,传递给函数的是它的实际参数的隐式引用(即实际参数的地...

    jcc 评论0 收藏0
  • 讲清楚之 javascript 参数传值

    摘要:讲清楚之参数传值参数传值是指函数调用时,给函数传递配置或运行参数的行为,包括通过进行传值。所以对的赋值会改变上下文栈中标识符保存的具体值此时如果使用的是按引用传递,则变量所指向的对象因该也被赋值为。 讲清楚之 javascript 参数传值 参数传值是指函数调用时,给函数传递配置或运行参数的行为,包括通过call、apply 进行传值。 在实际开发中,我们总结javascript参数传...

    itvincent 评论0 收藏0
  • 讲清楚之 javascript 参数传值

    摘要:讲清楚之参数传值参数传值是指函数调用时,给函数传递配置或运行参数的行为,包括通过进行传值。所以对的赋值会改变上下文栈中标识符保存的具体值此时如果使用的是按引用传递,则变量所指向的对象因该也被赋值为。 讲清楚之 javascript 参数传值 参数传值是指函数调用时,给函数传递配置或运行参数的行为,包括通过call、apply 进行传值。 在实际开发中,我们总结javascript参数传...

    ZoomQuiet 评论0 收藏0
  • JavaScript设计模式

    摘要:可能因为先入为主,在编程之中,往往不由自主地以的逻辑编程思路设计模式进行开发。这是原型模式很重要的一条原则。关于闭包与内存泄露的问题,请移步原型模式闭包与高阶函数应该可以说是设计模式的基础要领吧。在下一章,再分享一下的几种常用设计模式。 前 在学习使用Javascript之前,我的程序猿生涯里面仅有接触的编程语言是C#跟Java——忽略当年在大学补考了N次的C与VB。 从静态编程语言,...

    keke 评论0 收藏0
  • call by sharing——JavaScript中“共享传参”和“按值传参”理解

    摘要:众所周知,中参数是按值传递的。先大概介绍按值传参基本类型基本类型的参数传递比较简单,示例代码的值复制给了函数内部的局部变量所以在函数内部改变的值并不会影响外部的值。 众所周知,JavaScript中参数是按值传递的。与访问变量不同,基本类型和引用类型的参数在传递时都如同变量的复制。 但是我们在使用引用类型的参数传递时,经常会发现在函数内改变引用类型参数(如对象)会在函数外反映出来,这种...

    jsdt 评论0 收藏0

发表评论

0条评论

itvincent

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<