Nic*_*sen 31 c# static constants
上周末我遇到了一个开源项目,当时我碰到了一些代码,让我很困惑地查看了C#规范中的用法.
问题中的代码如下:
internal static class SomeStaticClass
{
private const int CommonlyUsedValue = 42;
internal static string UseCommonlyUsedValue(...)
{
// some code
value = CommonlyUsedValue + ...;
return value.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
我被猝不及防,因为这似乎是静态函数使用的非静态字段,有些如何在静态类中编译得很好!
规范声明(§10.4):
常量声明可以包括一组属性(§17),一个新修饰符(§10.3.4),以及四个访问修饰符的有效组合(§10.3.5).属性和修饰符适用于constant-declaration声明的所有成员.尽管常量被认为是静态成员,但常量声明既不需要也不允许使用静态修饰符.同一修饰符在常量声明中多次出现是错误的.
所以现在它更有意义,因为常量被认为是静态成员,但句子的其余部分对我来说有点令人惊讶.为什么常量声明既不需要也不允许使用静态修饰符?不可否认,我不知道这个规范是否足以让它立即变得有意义,但为什么决定不强制常量使用静态修饰符如果它们被认为是静态的?
查看该段落中的最后一句,我无法弄清楚它是否直接与前一个语句有关,并且在常量上有一些隐式静态修饰符,或者它是否作为常量的另一个规则.任何人都可以帮我解决这个问题吗?
Eri*_*ert 60
更新:这个问题是我的博客2010年6月10日的主题.感谢您提出的好问题!
为什么决定不强制常量使用静态修饰符,如果它们被认为是静态的?
假设常量被认为是静态的.有三种可能的选择:
使静态可选:"const int x ..."或"static const int x ..."都是合法的.
make static required:"const int x ..."是非法的,"static const int x ..."是合法的
使静态非法:"const int x ..."是合法的,"static const int x ..."是非法的.
你的问题是我们为什么选择(3)?
1999年的设计说明没有说; 我刚刚检查过 但是我们可以推断出语言设计师的头脑可能会发生什么.
(1)的问题是你可以阅读同时使用"const int x ..."和"static const int y ..."的代码,然后你自然会问自己"有什么区别?" 由于非常量字段和方法的默认值是"实例",除非是"静态",因此自然的结论是某些常量是每个实例,而某些常量是每个类型,并且这个结论是错误的.这很糟糕,因为它具有误导性.
(2)的问题是,首先,它是多余的.这只是更多的打字而没有增加语言的清晰度或表现力.第二,我不了解你,但我个人讨厌它,当编译器给我错误"你忘了在这里说出这个神奇的词.我知道你忘了说出这个神奇的词,我百分之百能干弄明白这个神奇的词需要去那里,但是除非你说出神奇的词,否则我不会让你完成任何工作.
(3)的问题是开发人员需要知道const逻辑意味着静态.然而,一旦开发人员了解到这一事实,他们就已经学会了这一点.这不是一个很难弄清楚的复杂想法.
向最终用户提出最少问题和成本的解决方案是(3).
将这与其他地方进行比较和对比很有意思,因为语言中做出了不同的决定.
例如,重载运算符必须是公共的和静态的.在这种情况下,我们再次遇到三种选择:
使public static可选,
使它成为必需品,或
把它变成非法的.
对于重载运算符,我们选择(2).由于方法的自然状态是私有/实例,因此(1)和(3)都需要,使得看起来像公共/静态方法看起来像公共/静态的方法似乎是奇怪和误导的.
再例如,与基类中的虚方法具有相同签名的虚方法应该在其上具有"新"或"覆盖".再次,三个选择.
使它成为可选:你可以说新的,或覆盖,或者什么都不说,在这种情况下我们默认为new.
使它成为必需:你必须说新的或覆盖,或
使它成为非法:你根本不能说新的,所以如果你不说覆盖那么它会自动成为新的.
在这种情况下,我们选择(1),因为最适合人的脆基类的情况增加了一个虚拟的方法,你不知道你现在正在重写的基类.这会产生警告,但不会产生错误.
我的观点是,必须根据具体情况考虑这些情况.这里没有太多的一般指导.
Ree*_*sey 43
基本上,const已经意味着静态,因为在运行时无法更改值.你没有理由声明静态const,因为它已经隐含了,语言设计者决定让语言语法反映出来.
规范语言基本上是说"Const总是静态的,所以你不能明确地说静态和const,因为它是多余的."
它不是必需的或允许的,因为它是多余的.如果所有const成员都是静态的,那么只允许将其中一些成员指定为static并且其中一些成员不成为混淆.