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#编译器如此难以支持以下内容:
- Members functions marked
const
. - References to data types (other than string) marked
const
, through which onlyconst
member functions can be called ?
成员函数标记为const。
引用标记为const的数据类型(字符串除外),通过它只能调用const成员函数?
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).
我相信如果C#支持这个会非常有用。首先,它真的有助于看似广泛的同性恋放弃C#程序员返回裸体引用私人数据(至少这是我在我的工作场所看到的)。
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)
或者C#中已经存在一些与我相同的东西? (我知道readonly和const关键字,但它们并没有真正满足上述目的)
5 个解决方案
#1
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.
常量应该适用于对象还是引用?如果它在引用中,那么这应该只是编译时,还是在引用本身内?对于同一个对象有非const引用的其他东西可以在引擎盖下摆弄吗?
您是否希望能够在C ++中将其丢弃?这听起来不像你在托管平台上想要的东西......但是那些在C ++中有意义的时候呢?
当声明中涉及多个类型时,语法变得棘手(IMO) - 想想数组,泛型等等。很难确切地确定哪个位是const。
如果你不能把它扔掉,每个人都必须把它弄好。换句话说,.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. There's rather a lot of commentary on the relevant bug which you may find interesting.
编辑:关于Java社区中这种肆虐的争论多年来一直存在争议。对相关的bug有很多评论,你可能会觉得有趣。
#2
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).
正如乔恩已经涵盖的那样(当然)const的正确性并不像看起来那么简单。 C ++以一种方式做到了。 D做另一种(可以说是更正确/有用)的方式。 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. This means that nothing can ever change the state once initialised.
D引入了另一个关键字 - 不变量 - 它适用于对象本身。这意味着一旦初始化就没有任何东西可以改变状态。
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.
这种安排的好处是const方法可以接受const和不变对象。因为不变的对象是功能世界的面包和黄油,而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). .Net was originally defined when things were more hazy, so didn't commit to too much - and now it's too late to retrofit.
回到正轨 - 我认为我们现在只是(后半部分的顽皮分子)了解如何最好地使用const(和不变量)。 .Net最初是在事情变得更加朦胧的时候定义的,所以没有做太多的承诺 - 现在改造已经太晚了。
I'd love to see a port of D run on the .Net VM, though :-)
我很想在.Net VM上看到D的端口,但是:-)
#3
Mr. Heljsberg, the designer of the C# language has already answered this question:
C#语言的设计师Mr. Heljsberg已回答了这个问题:
#4
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.
如果将不可变类型添加到C#的未来版本中,我不会感到惊讶。 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.
我认为,由于扩展旨在包含并行性,您可能会看到不变性越来越多。
#5
The question is, do we need constness in C#?
问题是,我们是否需要C#中的const?
-
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 ofcallvirt
?)我很确定JITter知道给定的方法不会影响对象本身并自动执行相应的优化。 (可能是通过发出呼叫而不是呼叫?)
-
I'm not sure we need those, since most of the pros of constness are performance related, you end up at the point 1.
我不确定我们是否需要这些,因为const的大部分专业都与性能有关,你最终会在第1点结束。
Besides that, C# has the readonly
keyword.
除此之外,C#还有readonly关键字。
#1
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.
常量应该适用于对象还是引用?如果它在引用中,那么这应该只是编译时,还是在引用本身内?对于同一个对象有非const引用的其他东西可以在引擎盖下摆弄吗?
您是否希望能够在C ++中将其丢弃?这听起来不像你在托管平台上想要的东西......但是那些在C ++中有意义的时候呢?
当声明中涉及多个类型时,语法变得棘手(IMO) - 想想数组,泛型等等。很难确切地确定哪个位是const。
如果你不能把它扔掉,每个人都必须把它弄好。换句话说,.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. There's rather a lot of commentary on the relevant bug which you may find interesting.
编辑:关于Java社区中这种肆虐的争论多年来一直存在争议。对相关的bug有很多评论,你可能会觉得有趣。
#2
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).
正如乔恩已经涵盖的那样(当然)const的正确性并不像看起来那么简单。 C ++以一种方式做到了。 D做另一种(可以说是更正确/有用)的方式。 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. This means that nothing can ever change the state once initialised.
D引入了另一个关键字 - 不变量 - 它适用于对象本身。这意味着一旦初始化就没有任何东西可以改变状态。
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.
这种安排的好处是const方法可以接受const和不变对象。因为不变的对象是功能世界的面包和黄油,而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). .Net was originally defined when things were more hazy, so didn't commit to too much - and now it's too late to retrofit.
回到正轨 - 我认为我们现在只是(后半部分的顽皮分子)了解如何最好地使用const(和不变量)。 .Net最初是在事情变得更加朦胧的时候定义的,所以没有做太多的承诺 - 现在改造已经太晚了。
I'd love to see a port of D run on the .Net VM, though :-)
我很想在.Net VM上看到D的端口,但是:-)
#3
Mr. Heljsberg, the designer of the C# language has already answered this question:
C#语言的设计师Mr. Heljsberg已回答了这个问题:
#4
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.
如果将不可变类型添加到C#的未来版本中,我不会感到惊讶。 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.
我认为,由于扩展旨在包含并行性,您可能会看到不变性越来越多。
#5
The question is, do we need constness in C#?
问题是,我们是否需要C#中的const?
-
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 ofcallvirt
?)我很确定JITter知道给定的方法不会影响对象本身并自动执行相应的优化。 (可能是通过发出呼叫而不是呼叫?)
-
I'm not sure we need those, since most of the pros of constness are performance related, you end up at the point 1.
我不确定我们是否需要这些,因为const的大部分专业都与性能有关,你最终会在第1点结束。
Besides that, C# has the readonly
keyword.
除此之外,C#还有readonly关键字。