【问题标题】:Why doesn't C# offer constness akin to C++?为什么 C# 不提供类似于 C++ 的常量?
【发布时间】:2009-02-09 13:27:57
【问题描述】:

C# 中的引用与 C++ 中的引用非常相似,只是它们是垃圾回收的。

为什么 C# 编译器很难支持以下内容:

  1. 标记为const的成员函数。
  2. 对标记为const的数据类型(字符串除外)的引用,通过它只能调用const的成员函数?

我相信如果 C# 支持它会非常有用。一方面,它确实有助于看似广泛的同性恋放弃,C# 程序员返回对私有数据的裸引用(至少这是我在工作场所看到的)。

或者在 C# 中是否已经存在我缺少的等效项? (我知道readonlyconst 关键字,但它们并不能真正达到上述目的)

【问题讨论】:

    标签: c# compiler-construction reference constants


    【解决方案1】:

    我怀疑有一些实际原因,还有一些理论上的原因:

    • 常量应该应用于object还是reference?如果它在参考中,这应该只是编译时的,还是参考本身的一点?对同一个对象有非常量引用的其他东西可以在引擎盖下摆弄它吗?
    • 您希望能够像在 C++ 中那样将其丢弃吗?这听起来不太像您在托管平台上想要的东西......但是在 C++ 中有意义的所有时候呢?
    • 当您在声明中涉及多个类型时,语法会变得很棘手 (IMO) - 想想数组、泛型等。很难准确确定哪个位是 const。
    • 如果你不能把它扔掉,每个人都必须把它做好。换句话说,您使用的 .NET 框架类型和任何其他 3rd 方库都必须做正确的事情,否则您会遇到令人讨厌的情况,即您的代码由于一个微妙的问题而无法做正确的事情恒定性。

    虽然现在无法支持,但原因很重要:

    • 向后兼容性:不可能所有库都正确迁移到它,这使它几乎毫无用处:(

    我同意拥有某种 constness 指标会很有用,但恐怕我看不到它的发生。

    编辑:多年来,Java 社区一直存在关于这种激烈争论的争论。 relevant bug 上有很多评论,您可能会觉得有趣。

    【讨论】:

    • 谢谢乔恩。这很有启发性。
    【解决方案2】:

    正如 Jon 已经介绍的(当然), const 正确性并不像看起来那么简单。 C++ 以一种方式做到这一点。 D 以另一种方式(可以说更正确/有用)。 C# 与它调情,但没有做任何更大胆的事情,正如您所发现的(而且可能永远不会很好,正如 Jon 再次很好地介绍的那样)。

    也就是说,我相信 Jon 的许多“理论原因”在 D 的模型中得到了解决。

    在 D (2.0) 中, const 的工作方式与 C++ 非常相似,只是它是完全可传递的(因此应用于指针的 const 将应用于指向的对象、该对象的任何成员、该对象具有的任何指针、它们的对象指向等)-但很明显,此 only 适用于您声明为 const 的变量(因此,如果您已经有一个非常量对象并且您将 const 指针指向它,则非-const 变量仍然可以改变状态)。

    D 引入了另一个关键字 - 不变 - 它适用于对象本身。这意味着一旦初始化,任何东西都无法改变状态。

    这种安排的美妙之处在于 const 方法可以接受 const 和不变对象。由于不变量对象是函数世界的面包和黄油,而 const 方法在函数意义上可以被标记为“纯”——即使它可以与可变对象一起使用。

    回到正轨 - 我认为我们现在(后半部分顽皮)才了解如何最好地使用 const(和不变量)。 .Net 最初是在事情比较模糊的时候定义的,所以并没有做出太多承诺——现在改造已经太晚了。

    不过,我希望看到 D 的端口在 .Net VM 上运行 :-)

    【讨论】:

      【解决方案3】:

      Mr. Heljsberg,C#语言的设计者已经回答了这个问题:

      http://www.artima.com/intv/choicesP.html

      【讨论】:

      • 有趣,我没见过。不过,我认为从功能的角度来看(正如我在回复中提出的那样),任何困难都是值得的。
      【解决方案4】:

      如果不可变类型被添加到 C# 的未来版本中,我不会感到惊讶。 C# 3.0 已经朝着这个方向发展。

      例如,匿名类型是不可变的。

      我认为,由于旨在包含并行性的扩展,您可能会看到越来越多的不可变性出现。

      【讨论】:

        【解决方案5】:

        问题是,我们需要 C# 中的 constness 吗?

        1. 我很确定 JITter 知道给定的方法不会影响对象本身并自动执行相应的优化。 (也许通过发出 call 而不是 callvirt ?)

        2. 我不确定我们是否需要这些,因为 constness 的大多数优点都与性能相关,所以你最终会得到第 1 点。

        除此之外,C# 还有 readonly 关键字。

        【讨论】:

        • 我不同意您的说法,即“大多数 constness 的优点都与性能有关”——我想说大多数都与正确性和可维护性有关。
        • 这不是为了JITter的方便,而是为了程序员。在 C++ 中,如果我尝试更改 const 对象,编译器会给我一个错误。因此,例如,我可以从我的方法中返回 const 引用。在 C# 中,每个人似乎都在返回外部任何人都可以更改的引用。危险!
        猜你喜欢
        • 2016-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-31
        • 1970-01-01
        • 1970-01-01
        • 2021-12-28
        相关资源
        最近更新 更多