为什么在C#中不能声明静态结构体,但可以有静态方法?

43
// OK
struct MyStruct
{
    static void Foo() { }
}

// Error
static struct MyStruct
{
}

对于委托枚举同样适用。 - nawfal
我在另一个问题中回答了这个问题。希望能帮到你。 这是链接 - user6755993
3个回答

43

由于无法创建静态类型的实例,static struct 的行为与 static class 完全相同。因此,没有必要创建它们。我认为理论上有可能拥有一个static struct,但这会令人困惑 - 如果两者的行为完全相同,那么你如何在 static classstatic struct 之间进行选择?

请注意,结构体中的static方法非常有用,因为您可以将它们用于与结构体相关的操作,例如DateTime.TryParse等。

就技术而言,我认为当前的C#编译器和运行时不可能产生像static struct这样的东西,因为在内部(在IL级别), static class 是一个标记为abstractsealed的类。我想你无法创建一个在 IL 中被标记为abstractsealedstruct


固定数组只能包含在结构体中,拥有一个静态的固定数组会很好。 - Markus

15

我认为关键在于结构体是值类型而不是引用类型。这就像说“整个程序只有一个int实例,它可以有不同的值,但一次只能有一个值”。此外,每当你将结构体作为参数传递时,它会被按值传递,也就是说,结构体的副本会被创建并放置在堆栈上。这违背了静态定义的目的——它应该意味着正在定义的东西只有(永远只有)一个实例。如果你想创建的确实是Singleton,那么使用类比使用结构体更好,因为它具有比结构体更好的创建语义。


10
重要的一点是,类上的 static 修饰符强制(其中之一)不允许创建类的实例。这是通过强制私有构造函数来完成的。
CLR 没有任何方法可以防止创建结构体类型的实例。即使没有公共默认构造函数,只需声明:
struct S { }

S[] items = new S[]{1};

创建结构体的实例时,所有相关存储器都将被设置为零比特。

请注意,这与引用类型(类)不同,在引用类型中,同样的代码会创建指定类型的引用(引用没有对象,也就是空引用),但不会创建对象本身的实例。


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