为什么C#静态构造函数需要使用括号?

3

请考虑:

class Foo
{
    static Foo()
    {
        // Static initialisation
    }
}

为什么()static Foo() {...} 中是必需的?静态构造函数必须始终是无参的,所以有什么必要吗?这些括号是为了避免某些解析器歧义,还是只是为了保持与常规无参构造函数的一致性?
由于它看起来非常像初始化块,我经常会不小心将它们省略掉,然后需要思考几秒钟才能发现问题。如果它们可以以同样的方式省略,那将是很好的。

如果您对语言设计的这些方面感兴趣,您可能想阅读我关于类似设计问题的文章:http://blogs.msdn.com/b/ericlippert/archive/2010/09/20/ambiguous-optional-parentheses.aspx - Eric Lippert
@Eric Lippert:我已经是你博客的忠实读者了(我想那也是我学到“省略”的词)。:) 但是重新阅读这些文章后,似乎在方法/构造函数调用中使空括号可选所创建的任何歧义都不适用于静态构造函数的情况(主要是因为你不能显式地调用它)。在这种情况下是否也存在歧义,还是说这只是一个不值得关注的问题? - verdesmarald
3个回答

11

因为它是一个静态的构造函数,所以它是static + 一个看起来普通的构造函数。

保持一致性很重要。 :-)


6
我经常遇到这种问题,即“编译器可以确定缺少某个东西,那么为什么需要它?”以下是另一个类似问题的例子:
C#在静态类中使用常量
正如我在那个问题中指出的那样,基本上我们在这种情况下有三种选择。使冗余文本必需,使其可选,或使其非法。
每个都有自己的缺点。
使其必需的缺点是您最终会在语言中产生不必要的冗余。
使其可选的缺点是会让认为两种形式之间必须有区别的人感到困惑。此外,这将使错误恢复解析器更难工作;它依赖于冗余。而且,您可能会使将来添加新语言功能变得更加困难,因为已经声明了更多的“语法区域”。
使其非法的缺点是您会发现一个“陷阱”,用户必须记住哦,是应该在这里放括号,但不是在这里。
提出的功能最好有一个好处来弥补不足。对我来说,最小的不利之处似乎是第一个:使其成为必需品。其他选项我希望有一个可以证明不利之处的好处,但我在这里没有看到一个。

有趣的是,在 static const 的情况下,你倾向于认为“这只是增加了打字的工作量,而没有为语言增加清晰度或表现力”,但在这种情况下,却是“可能会使未来添加新语言特性更加困难”。我想这是一个冗余程度与潜在损失之间的权衡吧? - verdesmarald
@veredesmarald:没错,每次都需要做出判断。在这种情况下,我认为仅仅在这种情况下使其成为可选项会产生奇怪的不一致性;为什么不能允许任何没有参数的方法省略其参数列表呢?静态构造函数有什么特别之处? - Eric Lippert
同样有趣的是,您提到将其设为非法会创建一个“陷阱”,而我发现“陷阱”在于必须包含它们。我认为这是我频繁使用不带参数的构造函数初始化程序以及来自我的Java时代的遗留问题,其中 static 块没有圆括号的组合。 - verdesmarald
正如您在系列中提到的那样,您不能使它们在任何调用中都是可选的,因为这会导致歧义;静态cons是特殊的,因为所提到的歧义不适用于它们(就我所知),因为它们可以出现的位置数量有限。我想我可以理解不一致的角度,尽管在我看来,静态cons已经是一个与常规cons/方法调用不同的东西,也许这只是我看待语言某些方面的奇怪之处。 - verdesmarald

1
我认为这是为了消除歧义:它使解析器的工作更容易,将代码块识别为一个构造子例程(无论是否static);反过来,它也有助于确保人类作者/维护者意识到选择这个特定结构的影响,通过强制他们使用特定的方法式语法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接