一个静态结构体方法和一个静态类方法有什么区别?

13

我最近发现C#中的结构体可以有方法。

意外地,我发现自己在代码中使用了一个空结构体的静态方法,而不是我以为正在使用的静态类的静态方法!

例如:

public struct Foo
{
    public static void Bar(Param param)
    {
        ...
    }
}

目前这个结构体并没有被用作结构体,因为它根本没有任何属性!

这和使用类的静态方法(无论是静态还是非静态)有什么不同吗?有没有理由更喜欢其中一种?(我的直觉告诉我,使用静态结构体方法至少不太直观)

2个回答

24

不,静态成员属于类型而不是类型的实例。声明静态类成员和静态结构成员之间在性能和语义方面没有区别。

需要注意的是,如果一个类型的唯一功能是包含静态成员,则应该使用静态类。使用结构体时,会有一个隐式且无法更改的公共、无参数构造函数。如果该类型不会有任何实例方法,则应该去除创建实例的能力。声明一个类为static就相当于声明它为abstract sealed,这样开发人员将不能意外地创建没有用处的实例。


3
将一个类声明为 static 的好处(相对于 abstract sealed)是让编译器能够将该类型在变量声明或类型转换中的任何用法标记为错误。 - Mike Zboray
@mikez 还有,将任何实例成员声明标记为错误。 - cdhowie
3
@mikez,我认为更重要的区别是“抽象密封类”在C#中是无效的。 - svick
当然,我的观点是人们不应该认为“静态类”和“抽象密封类”是“相同的”。与抽象和密封类所授予的限制相比,静态类有额外的限制。 - Mike Zboray
关于struct的有趣之处就在于,如果没有非静态数据,则在使用“隐式”无参数实例构造函数之前,已经给你的实例分配了。例如下面是可以的:static void Example() { Foo local; var okStr = local.ToString(); var okBool = local.Equals(local); } 这里的Foo是像问题中的那样的一个结构。有趣的是,local看起来未赋值,但由于没有实例字段,因此每个字段都是(真空)分配的,因此这不是对未分配变量的使用。C#编译器很高兴并且运行正常。 - Jeppe Stig Nielsen

3

这种行为并没有什么不同。C#通过大幅增加结构体和类的特性交集来玷污了结构体。个人认为应该使用类,因为这对我来说更正确(在大多数语言中也更符合惯例)。


在C++中已经可以为结构定义方法和构造函数,因此这不是C#首次引入的全新功能。 - Jagger
一个有 [StructLayout(LayoutKind.Explicit)] 属性的结构体,怎么替换成类呢? - Mike de Klerk

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