【发布时间】:2011-06-24 03:29:07
【问题描述】:
我很高兴 C# 不允许您访问静态成员,就像它们是实例成员一样。这避免了 Java 中的一个常见错误:
Thread t = new Thread(..);
t.sleep(..); //Probably doesn't do what the programmer intended.
另一方面,它确实允许您“通过”派生类型访问静态成员。除了运算符(它使您免于编写强制转换)之外,我想不出任何实际有用的情况。事实上,它积极鼓励错误,例如:
// Nasty surprises ahead - won't throw; does something unintended:
// Creates a HttpWebRequest instead.
var ftpRequest = FtpWebRequest.Create(@"http://www.stackoverflow.com");
// Something seriously wrong here.
var areRefEqual = Dictionary<string, int>.ReferenceEquals(dict1, dict2);
当我在不熟悉的 API 中寻找方法时,我个人会一遍又一遍地犯下类似的错误(我记得从表达式树开始;我在编辑器中点击了BinaryExpression.,我想知道为什么 IntelliSense 到底为我提供了@987654325 @ 作为一个选项)。
在我(短视)看来,此功能:
- 不会减少冗长;程序员必须以一种或另一种方式指定类型名称(不包括运算符和访问当前类型的继承静态成员的情况)。
- 鼓励出现上述错误/误导性代码。
- 可能会向程序员建议 C# 中的静态方法表现出某种“多态性”,而实际上它们没有。
- (次要)在重新编译时引入“静默”,可能是意外的重新绑定可能性。
(IMO,运营商是一个特殊情况,值得他们自己讨论。)
鉴于 C# 通常是“成功之坑”语言,为什么会有这个特性?我看不到它的好处(除了“可发现性”,它总是可以在 IDE 中解决),但我看到了很多问题。
【问题讨论】:
-
或者,更糟糕的是,
UTF8Encoding.ASCII。 -
我同意这可能会有点误导,但它符合继承的成员被视为派生类型的成员的原则。请注意,我们明确not 允许在受约束的类型参数上使用此模式,因为那样它确实具有潜在的误导性。详情请见blogs.msdn.com/b/ericlippert/archive/2007/06/14/…。
标签: c# inheritance static language-design