热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

价值和参考类型混淆

如何解决《价值和参考类型混淆》经验,为你挑选了1个好方法。

我在每个网站上都有关于这个主题的内容,并且通过Jon Skeets关于参考和值以及参数传递的文章阅读了过去几天.我理解这两种类型的概念,它们代表什么以及与Value和Reference参数的区别是什么是另一种规范.

我理解这是如何工作的,以及如何使用它,但我不明白有人在谈论这个话题.你们所有人都说,例如int是一个值类型,并且string是一个引用类型.但根据我的理解,类型基本上只取决于它们被声明的类的类型.

看看这段代码片段,了解我的意思:

public struct IntHolder
{
   public int number;
}

IntHolder first = new IntHolder();
first.number = 5;
IntHolder secOnd= first;
first.number = 6;

现在second.number值为5.如果你struct改为class,number就会像引用类型一样,所以int在generell中根本不是一个值类型,它只是类的类型.同样的例子也适用于string......

显然,声明对象的类的类型设置了对象的类型,或者我错过了一个核心概念.请纠正我并帮助我理解它是正确的,或者告诉我这背后的意义是什么int string......等等......即使它们初始化时无关紧要,所以基本上总是如此.



1> poke..:

这与您要更改的字段类型无关.这里的相关内容实际上只是父类型的类型:

IntHolder first = new IntHolder();
IntHolder secOnd= first;

根据具体IntHolder情况有两种不同的效果:

对于值类型(struct),这将创建一个副本.值类型对象的数据与对象一起存在,因此所有数据都被复制.它有点像这样:

IntHolder secOnd= new IntHolder();
second.number = first.number;
// and all other fields (visible or not) are copied too

这意味着对复制值类型的字段的赋值将覆盖该值而不会影响原始对象.这就像局部变量的行为:

var x = 5;
var y = 2;
y = 3; // this does not change x

但是,当类型是引用类型时,赋值secOnd= first只会复制引用.保存值的基础对象对于两者都是相同的.因此,对任一对象的更改都会影响另一个 - 因为没有"其他":它是由两个单独的变量引用的相同对象.


要回答评论中的后续问题:

我如何想象一个int变量是一个值类型并且string是一个引用类型?我的意思是,所以int变量直接包含数字,string变量就像指向字符串对象存储位置的指针一样?

是的,就是这样.引用的值基本上只是指向对象实际存在的内存的指针,而值类型的值是整个对象本身.

这就是为什么例如将值类型作为方法的参数意味着当调用该方法时,整个值类型对象被复制到堆栈中以执行该方法.

作为值类型的类型并不意味着它的成员也都是值类型.例如,值类型中的字符串成员的实际存储值仍然是对字符串对象的引用.类似地,引用类型的实际内存将包含值类型的实际值,以及对引用类型的其他内存位置的引用.

如果父类型总是比对象类型更重要,那么我可以使用int和string的类型?

没有什么比另一个更重要了.作为值或引用类型的对象仅对该对象的存储方式有影响.对于对象的成员,这是完全单独评估的.

是否有可能只有一个类和一堆变量来设置其中一些变量作为对另一个变量的引用,例如int变量.

您不能拥有值类型的引用指针,就像您可以在C中一样,没有.但是,您可以引用允许您改变值类型的字段值的字段.例如:

class Test
{
    private int field;

    public void ShowExample()
    {
        // set the value
        field = 12;

        // call the method and pass *a reference* to the field
        // note the special syntax
        MutateField(ref field);

        // the field, which is a value type, was mutated because it was passed as a reference
        Console.WriteLine(field == 4);
    }

    private static void MutateField(ref int value)
    {
        value = 4;
    }
}


推荐阅读
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文介绍了在Java中gt、gtgt、gtgtgt和lt之间的区别。通过解释符号的含义和使用例子,帮助读者理解这些符号在二进制表示和移位操作中的作用。同时,文章还提到了负数的补码表示和移位操作的限制。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
author-avatar
噯嘅坟墓_996
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有