简体   繁体   English

为什么C#不提供类似于C ++的constness?

[英]Why doesn't C# offer constness akin to C++?

References in C# are quite similar to those on C++, except that they are garbage collected. C#中的引用与C ++中的引用非常相似,只是它们是垃圾回收的。

Why is it then so difficult for the C# compiler to support the following: 为什么C#编译器支持以下内容如此困难:

  1. Members functions marked const . 成员函数标记为const
  2. References to data types (other than string) marked const , through which only const member functions can be called ? 引用标记为const数据类型(字符串除外),通过它只能调用const成员函数?

I believe it would be really useful if C# supported this. 我相信如果C#支持这个会非常有用。 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). 首先,它真的有助于看似广泛的同性恋放弃C#程序员返回裸体引用私人数据(至少这是我在我的工作场所看到的)。

Or is there already something equivalent in C# which I'm missing? 或者在C#中我已经缺少了相同的东西? (I know about the readonly and const keywords, but they don't really serve the above purpose) (我知道readonlyconst关键字,但它们并没有真正满足上述目的)

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? 对于同一个对象有非const引用的其他东西可以在引擎盖下摆弄吗?
  • Would you want to be able to cast it away as you can in C++? 您是否希望能够在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++? 这听起来不像你在托管平台上想要的东西......但是那些在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. 当声明中涉及多个类型时,语法会变得棘手(IMO) - 想想数组,泛型等等。很难确定哪个位是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. 换句话说,.NET框架类型和您使用的任何其他第三方库都必须做正确的事情,否则您将面临令人讨厌的情况,即您的代码无法做正确的事情,因为有一个微妙的问题常量性。

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. 编辑:关于Java社区中的这种肆虐已有多年的争论。 There's rather a lot of commentary on the relevant bug which you may find interesting. 相关的bug有很多评论,你可能会觉得有趣。

As Jon already covered (of course) const correctness is not as simple as it might appear. 正如乔恩已经涵盖的那样(当然)const正确性并不像看起来那么简单。 C++ does it one way. C ++以一种方式做到了。 D does it another (arguably more correct/ useful) way. D做另一种(可以说是更正确/有用)的方式。 C# flirts with it but doesn't do anything more daring, as you have discovered (and likely never well, as Jon well covered again). C#与它调情,但没有做任何更大胆的事情,正如你已经发现的那样(并且可能永远不会好,因为Jon再次覆盖了)。

That said, I believe that many of Jon's "theoretical reasons" are resolved in D's model. 也就是说,我相信Jon的许多“理论原因”在D模型中得到了解决。

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

D introduces another keyword - invariant - which applies to the object itself. D引入了另一个关键字 - 不变量 - 它适用于对象本身。 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. 这种安排的好处是const方法可以接受const和不变对象。 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. 由于不变对象是功能世界的面包和黄油,而const方法在功能意义上可以被标记为“纯粹” - 即使它可以与可变对象一起使用。

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). 回到正轨 - 我认为我们现在只是(后半部分的顽皮)了解如何最好地使用const(和不变量)。 .Net was originally defined when things were more hazy, so didn't commit to too much - and now it's too late to retrofit. .Net最初是在事情变得更加朦胧的时候定义的,所以并没有过多地承诺 - 现在改造已经太晚了。

I'd love to see a port of D run on the .Net VM, though :-) 我很想在.Net VM上看到D的端口,但是:-)

Mr. Heljsberg , the designer of the C# language has already answered this question: C#语言的设计师Mr. Heljsberg已回答了这个问题:

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

I wouldn't be surprised if immutable types were added to a future version of C#. 如果将不可变类型添加到C#的未来版本中,我不会感到惊讶。 There have already been moves in that direction with C# 3.0. 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. 我认为,由于扩展旨在包含并行性,您可能会看到不变性越来越多。

The question is, do we need constness in C#? 问题是,我们是否需要C#中的const?

  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. 我很确定JITter知道给定的方法不会影响对象本身并自动执行相应的优化。 (maybe by emitting call instead of callvirt ?) (也许通过发出call而不是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. 我不确定我们是否需要这些,因为constness的大多数专业人员都与性能有关,你最终会在第1点结束。

Besides that, C# has the readonly keyword. 除此之外,C#还有readonly关键字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM