低级别差异:非静态类与静态方法 vs. 静态类与静态方法

13
我想知道使用非静态类与静态方法相比,使用静态类具有哪些一般优点(或缺点)除了无法将静态方法用作非静态类的扩展方法之外。
例如:
class NonStaticClass
{
    public static string GetData()
    {
        return "This was invoked from a non-static class.";
    }
}

相对于这个:

static class StaticClass
{
    public static string GetData()
    {
        return "This was invoked from a static class.";
    }
}

使用一种方法而不是另一种方法的性能/内存影响是什么?

注意:假设我不需要实例化该类。我的用例场景仅限于类似这样的情况:

Console.WriteLine(NonStaticClass.GetData());
Console.WriteLine(StaticClass.GetData());
4个回答

16

主要的好处是,如果你将类设为静态的,编译器会确保你的类只有静态成员。

因此,任何阅读代码的人都会立即看到这个类无法实例化,并且没有与类的任何实例进行交互的考虑。因为根本就不可能有。

在clr级别上,不存在“静态”的概念。静态类既是“抽象”的又是“密封”的,这有效地阻止了继承和实例化。

至于性能方面,我没有看到编译器或运行时优化一个而不是另一个的可能性。

在这个例子中,我会专注于尽可能清晰地表达你的意图给读者。你总是可以以后再进行优化。


3

没有益处或劣势,这只是架构决策。

在提供功能集或函数库的情况下,请使用仅静态类。由于您无法实例化它,但可以像使用函数一样使用它。

MyMathLibrary.Plot(...)

这些类型通常意味着无状态行为。我再强调一遍,通常情况下是这样。

当您拥有“普通”类型但需要某种无状态方法时,请使用具有静态成员的简单类,例如:

public class MyType
{
    .... //some members 

    public static MyType ReadFromXml(XmlReader reader) {}
    public static void SaveToXml(MyType mt) {}
}

没有万能的解决方案,只是架构选择的问题。


@Dennis Delimarsky:为什么你说“我的使用情况场景仅限于……”?我不认为这是一种限制。根据你的架构,这可能是一个非常好的设计选择,通过明确你的API行为来实现。 - Tigran
这只是一个示例,我试图表明我并不打算实际实例化该类。 - Den

3

以下是需要注意的一些特殊情况/限制:

  • 无法实例化静态类
  • 无法继承静态类

因此,如果您希望为您的类(例如辅助工具/实用程序或扩展方法容器)设置这样的行为,并希望限制其使用,请将其设置为static


请查看我编辑后的帖子,了解一个使用案例场景 - 我想知道在不实例化的情况下使用它是否有任何区别。 - Den
4
除了您提到的要点之外:您还不能将静态类用作局部变量、字段或形式参数的类型。您不能将其用作数组的元素类型。您不能将其用作泛型类型参数列表中的类型参数。 - Eric Lippert
@FishBasketGordo:我们同时更新了我的答案。请再次进行更新,或者发表评论。 - abatishchev
@Dennis:一条关于编辑的备注实际是针对Fish的,我不小心提到了您,抱歉 :) - abatishchev

2
性能影响:基本上没有。
你可以创建一个NonStaticClass的实例,但由于它没有非静态重写方法,所以它几乎和说object obj = new object()一样有用,也就是说,它可能对锁定有用,但仅此而已。将类设置为静态可以防止某人新建它,但这并不会造成任何实际的伤害。
这更像是一种自我记录的方式,表明没有理由创建该类的实例。

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