为什么 C# 不提供类似于 C++ 的常量性?

发布于 2024-07-13 21:31:40 字数 406 浏览 5 评论 0原文

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

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

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

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

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

References in C# are quite similar to those on C++, except that they are garbage collected.

Why is it then so difficult for the C# compiler to support the following:

  1. Members functions marked const.
  2. References to data types (other than string) marked const, through which only const member functions can be called ?

I believe it would be really useful if C# supported this. For one, it'll really help the seemingly widespread gay abandon with which C# programmers return naked references to private data (at least that's what I've seen at my workplace).

Or is there already something equivalent in C# which I'm missing? (I know about the readonly and const keywords, but they don't really serve the above purpose)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

风向决定发型 2024-07-20 21:31:40

我怀疑有一些实际原因和一些理论原因:

  • 常量应该应用于对象还是引用? 如果它在参考中,这应该只是编译时,还是作为参考本身的一部分? 具有对同一对象的非常量引用的其他东西是否可以在幕后操纵它?
  • 您想像在 C++ 中一样将其丢弃吗? 这听起来不太像您在托管平台上想要的东西……但是在 C++ 中它有意义的所有时候又如何呢?
  • 当声明中涉及多个类型时,语法会变得很棘手(IMO) - 想想数组、泛型等。很难准确地计算出哪一位是 const。
  • 如果你无法摆脱它,每个人都必须把它做好。 换句话说,.NET 框架类型和您使用的任何其他第三方库都必须做正确的事情,否则您将面临令人讨厌的情况,即您的代码由于一个微妙的问题而无法做正确的事情恒定性。

不过,现在无法支持它的原因有一个很大的原因:

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

我同意它会拥有某种常量指示器是有用的,但恐怕我看不到它发生。

编辑:多年来,Java 社区对此一直存在争论,有很多关于 相关错误,您可能会感兴趣。

I suspect there are some practical reasons, and some theoretical reasons:

  • Should the constness apply to the object or the reference? If it's in the reference, should this be compile-time only, or as a bit within the reference itself? Can something else which has a non-const reference to the same object fiddle with it under the hood?
  • Would you want to be able to cast it away as you can in C++? That doesn't sound very much like something you'd want on a managed platform... but what about all those times where it makes sense in C++?
  • Syntax gets tricky (IMO) when you have more than one type involved in a declaration - think arrays, generics etc. It can become hard to work out exactly which bit is const.
  • If you can't cast it away, everyone has to get it right. In other words, both the .NET framework types and any other 3rd party libraries you use all have to do the right thing, or you're left with nasty situations where your code can't do the right thing because of a subtle problem with constness.

There's a big one in terms of why it can't be supported now though:

  • Backwards compatibility: there's no way all libraries would be correctly migrated to it, making it pretty much useless :(

I agree it would be useful to have some sort of constness indicator, but I can't see it happening, I'm afraid.

EDIT: There's been an argument about this raging in the Java community for ages. There's rather a lot of commentary on the relevant bug which you may find interesting.

安稳善良 2024-07-20 21:31:40

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

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

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

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

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

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

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

As Jon already covered (of course) const correctness is not as simple as it might appear. C++ does it one way. D does it another (arguably more correct/ useful) way. C# flirts with it but doesn't do anything more daring, as you have discovered (and likely never well, as Jon well covered again).

That said, I believe that many of Jon's "theoretical reasons" are resolved in D's model.

In D (2.0), const works much like C++, except that it is fully transitive (so const applied to a pointer would apply to the object pointed to, any members of that object, any pointers that object had, objects they pointed to etc) - but it is explicit that this only applies from the variable that you have declared const (so if you already have a non-const object and you take a const pointer to it, the non-const variable can still mutate the state).

D introduces another keyword - invariant - which applies to the object itself. This means that nothing can ever change the state once initialised.

The beauty of this arrangement is that a const method can accept both const and invariant objects. Since invariant objects are the bread and butter of the functional world, and const method can be marked as "pure" in the functional sense - even though it may be used with mutable objects.

Getting back on track - I think it's the case that we're only now (latter half of the naughties) understanding how best to use const (and invariant). .Net was originally defined when things were more hazy, so didn't commit to too much - and now it's too late to retrofit.

I'd love to see a port of D run on the .Net VM, though :-)

十六岁半 2024-07-20 21:31:40

Mr. Heljsberg, the designer of the C# language has already answered this question:

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

傾城如夢未必闌珊 2024-07-20 21:31:40

如果将不可变类型添加到 C# 的未来版本中,我不会感到惊讶。
C# 3.0 已经朝着这个方向迈出了一步。

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

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

I wouldn't be surprised if immutable types were added to a future version of C#.
There have already been moves in that direction with C# 3.0.

Anonymous types, for example, are immutable.

I think, as a result of extensions designed to embrace parallelism, you will be likely to see immutability pop up more and more.

滴情不沾 2024-07-20 21:31:40

问题是,我们在 C# 中需要常量吗?

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

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

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

The question is, do we need constness in C#?

  1. I'm pretty sure that the JITter knows that the given method is not going to affect the object itself and performs corresponding optimizations automagically. (maybe by emitting call instead of callvirt ?)

  2. I'm not sure we need those, since most of the pros of constness are performance related, you end up at the point 1.

Besides that, C# has the readonly keyword.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文