14

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

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

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

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

或者我在 C# 中已经有一些等价的东西了?(我知道readonlyandconst关键字,但它们并没有真正达到上述目的)

4

5 回答 5

17

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

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

就为什么现在不能支持它而言,有一个很大的原因:

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

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

编辑:多年来,Java 社区一直存在关于这种情况的争论。有很多关于相关错误的评论,您可能会觉得有趣。

于 2009-02-09T13:41:20.287 回答
6

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

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

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

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

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

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

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

于 2009-02-09T15:02:21.030 回答
5

C#语言的设计者Heljsberg先生已经回答了这个问题:

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

于 2009-02-09T15:05:45.933 回答
2

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

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

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

于 2009-02-12T11:08:39.277 回答
0

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

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

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

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

于 2009-02-09T13:40:06.607 回答