【问题标题】:What is a Value Class and what is a reference Class in C#?什么是 C# 中的值类和引用类?
【发布时间】:2010-12-12 03:40:31
【问题描述】:

C#中value classreference class的定义是什么?

这与value typereference type 有何不同?

我问这个问题是因为我在 MCTS 自定进度培训套件(考试 70-536)中读到了这个问题。第 1 章,第 1 课,第 4 课复习:

您需要创建一个简单的类或 只包含值的结构 类型。您必须创建课程或 结构,使其运行为 尽可能高效。你一定是 能够将类或结构传递给 无需担心的程序 程序将对其进行修改。哪一个 您应该创建以下内容吗?

一个参考类

B 参考结构

C值类

D值结构

正确答案:D

A 不正确:您可以创建一个 参考类;但是,它可能是 传递给过程时修改。

B 不正确:您无法创建 参考结构。

C 不正确:您可以创建一个值 班级;然而,结构往往是 更高效。

D 正确:值结构是 通常是最有效的。

【问题讨论】:

  • 在您编辑他的问题之前,他说的是“值类”和“参考类”,而不是“类型”。他可能引用了以下内容:icsi.berkeley.edu/~sather/Documentation/EclecticTutorial/…,其中说:“从根本上说:值类定义对象,一旦创建,就永远不会更改其值。值类型的变量只能通过重新分配来更改到那个变量。当我们只想修改值类的某个部分(比如说一个属性)时,我们不得不重新分配整个对象“......没有文章的链接,谁知道呢。
  • 我没有编辑问题。有人为我做了。这是一个糟糕的版本。我的意思是“价值类”和“参考类”。
  • 是的,我知道是 George Stocker 编辑了您的问题。我只是指出您的意思可能正是您输入的内容。看起来你刚刚澄清了这一点。
  • 我知道什么是值或引用类型,但我不知道什么是值或引用类。
  • 更新了问题。鉴于我从未听说过 C# 中的“价值类”或“参考类”,我几乎可以肯定 OP 在发布时犯了错误。 OP:请附上您所读内容的参考资料;否则会被视为印刷错误。

标签: c# .net oop terminology


【解决方案1】:

您可能会想到 C++/CLI,它与 C# 不同,它允许用户声明“值类”或“引用类”。 在 C# 中,您声明的任何类都将隐式成为引用类 - 只有内置类型、结构和枚举具有值语义。 要了解 C++/CLI 中的值类,请看这里: http://www.ddj.com/cpp/184401955

与 ref 类相比,值类的功能非常少,并且对于“普通旧数据”很有用;即没有身份的数据。由于您在将数据分配给另一个对象时正在复制数据,因此系统为您提供了一个默认(且强制)的复制构造函数,该构造函数只是将数据复制到另一个对象。

要将值类转换为引用类(从而将其放在垃圾收集堆上),您可以“装箱”它。

要确定您正在编写的课程是一个还是另一个,请问问自己它是否具有标识。这通常意味着它具有某种状态,或者具有标识符或名称,或者它自己的上下文的概念(例如指向附近节点的节点)。

如果不是,它可能是一个值类。

然而,在 C# 中,值类被声明为“结构”。

【讨论】:

    【解决方案2】:

    请参阅 the overview 关于该主题,但请认真关注 msnd 链接并阅读完整的 Common Type system 章节。 (您也可以在第一个问题的评论中提问)

    【讨论】:

      【解决方案3】:

      值类型通过值传递,而引用类型通过引用传递。

      编辑:值/参考类
      C# 中没有“值类”或“引用类”的概念,因此要求其定义是没有意义的。

      【讨论】:

      • 我添加了文档参考
      • 引用类型是按值传递的,但是传递的是引用。这是一个微妙但重要的区别。
      • 我明白你的意思。值类型变量直接包含数据,数据是按值传递的。引用类型变量包含对数据的引用,其中引用也是按值传递的。如果使用 ref 或 out,则变量通过引用传递。
      • 严格来说,是的,没有“值类”。但是有不可变的引用类型——例如系统字符串。它们的行为类似于值类型(默认情况下可以为空)。所以可以称它们为“价值类”。
      【解决方案4】:

      值类型存储实际数据,而引用类型存储对数据的引用。引用类型动态存储在堆上,而值类型存储在栈上。

      值类型:http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx 引用类型:http://msdn.microsoft.com/en-us/library/490f96s2.aspx

      【讨论】:

      【解决方案5】:

      当您引用值类型(即使用其名称)时,您指的是内存中数据所在的位置。因此,值类型不能为空,因为内存位置无法说“我不代表任何东西”。默认情况下,您按值传递值类型(也就是说,您传递给方法的对象不会因方法的执行而改变)。

      当您使用引用类型对象时,您实际上是在变相使用指针。该名称指的是内存位置,然后它引用了对象实际所在的内存位置。因此,您可以将 null 分配给引用类型,因为它们有一种说法:“我没有指向任何地方”。引用类型还允许对象随着方法的执行而改变,因此您可以通过将 myReferenceObject 的属性传递给方法调用来更改它。

      【讨论】:

        【解决方案6】:

        引用类型通过引用传递给方法,值类型通过值传递;在后一种情况下,方法接收变量的副本,而在前一种情况下,它接收对原始数据的引用。如果更改副本,则原件不会更改。如果您更改您引用的原始数据,则数据会在任何地方更改对数据的引用。如果在 C 中创建了与 C# 程序类似的程序,通常引用类型就像使用指针的数据,而值类型将是堆栈上的普通数据。

        数值类型、字符、日期、枚举和结构都是值类型。字符串、数组、委托和类(实际上,大多数东西)都是引用类型。

        【讨论】:

          【解决方案7】:

          如果我的理解是正确的,你可以通过使用readonly通过构造函数初始化的成员变量来完成一个“值类”,或者说不可变类。一旦创建,就无法更改。

          【讨论】:

            猜你喜欢
            • 2011-06-30
            • 2011-01-25
            • 1970-01-01
            • 2010-10-24
            • 2012-03-02
            • 2010-10-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多