C# 中的 "静态方法" 是什么?

198

当你在一个方法前面加上static关键字时,这意味着该方法属于类而不是属于实例,在使用该方法时无需创建类的实例对象。

public static void doSomething(){
   //Well, do something!
}

你可以向类中添加 static 关键字吗?如果加上它,会有什么意义?


12
你可以通过 class_name.static_method_name() 直接使用静态方法,而无需创建该类的实例。 - Javed Akram
在编程层面上,我们有一种感觉,即我们能够在不创建类/类型实例的情况下调用静态方法。但实际上,在内部并不是这样的。CLR 在内部管理一个特殊的实例,称为“类型实例”,用于管理对静态方法的调用。请参见此答案。它非常有趣。 - RBT
9个回答

344

静态函数与普通(实例)函数不同,它不与类的实例相关联。

静态类是一种只能包含静态成员的类,因此无法实例化。

例如:

class SomeClass {
    public int InstanceMethod() { return 1; }
    public static int StaticMethod() { return 42; }
}

为了调用InstanceMethod,你需要该类的一个实例:
SomeClass instance = new SomeClass();
instance.InstanceMethod();   //Fine
instance.StaticMethod();     //Won't compile

SomeClass.InstanceMethod();  //Won't compile
SomeClass.StaticMethod();    //Fine

35
这就像是一个类方法而不是实例方法吗? - Moshe
6
@Moshe:没错。使用静态方法时,你不需要类的实例来调用该方法,只需使用该类即可。 - Binary Worrier
3
调用一个静态方法是否存在某种技术限制,使其无法在实例上调用?如果编译器允许它,那么它可以被访问的危险是什么? - kroonwijk
3
@kroon说:“这没有任何意义。实例方法实际上只是将一个实例作为隐藏的第一个参数。静态方法则不需要。请查看我的博客文章:http://blog.slaks.net/2011/06/open-delegates-vs-closed-delegates.html。” - SLaks
其中,“StaticMethod”是类方法,“InstanceMethod”是类SomeClass的实例方法。 - Usman Younas

30

从另一个角度来看: 考虑您想对单个字符串进行一些更改。 例如,您想将字母大写等。 您可以创建另一个名为“Tools”的类来执行这些操作。 由于该类内没有任何实体可用(与“Person”或“Teacher”类相比),因此无需创建“Tools”类的实例。 因此,我们使用static关键字以便在不创建任何该类实例的情况下使用“Tools”类,并且当在类名“Tools”之后按下点时,您可以访问所需的方法。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Tools.ToUpperCase("Behnoud Sherafati"));
        Console.ReadKey();
    }
}

public static class Tools
{
    public static string ToUpperCase(string str)
    {
        return str.ToUpper();

    }
}
}

1
使用“在字符串上进行更改”的示例是不好的 - 字符串是不可变的,不能被更改。但是,除此之外,解释是有道理的(用非不可变类替换字符串)。 - Flydog57
@Flydog57 非不可变的只是可变的,哈哈哈哈 - Mindless

13
静态方法、字段、属性或事件可以在类上调用,即使没有创建类的实例。如果创建了类的任何实例,它们不能用于访问静态成员。静态字段和事件只存在一个副本,静态方法和属性只能访问静态字段和静态事件。静态成员通常用于表示不随对象状态而变化的数据或计算;例如,数学库可能包含用于计算正弦和余弦的静态方法。 静态类成员是在成员的返回类型之前使用 static 关键字声明的。

5

很快就会发现无法实例化静态类:

例如:

static class myStaticClass
{
    public static void someFunction()
    { /* */ }
}

您不能这样做:
myStaticClass msc = new myStaticClass();  // it will cause an error

您只能进行以下操作:

myStaticClass.someFunction();

5

静态函数意味着它与类相关联(不是类的特定实例,而是类本身),即使没有类的实例存在也可以调用。

静态类意味着类仅包含静态成员。


0

static 关键字的核心是只有一个 RAM 中的副本(方法/变量/类),这将被共享给所有调用。


0
当您在方法中添加“static”关键字时,它意味着底层实现会为类的任何实例提供相同的结果。不用说,结果会随参数值的变化而变化。

-1

静态变量不与类的对象链接。它可以使用类名访问。类的所有对象将共享静态变量。

通过将函数设置为静态,它将限制该文件内该函数的访问权限。


-8

当应用于类时,static关键字告诉编译器创建该类的单个实例。因此,无法“new”一个或多个该类的实例。静态类中的所有方法必须自身声明为静态。

通常希望非静态类具有静态方法是可行的,也是理想的。例如,当创建另一个类的实例的工厂方法通常被声明为静态,这意味着不需要包含工厂方法的类的特定实例。

有关如何、何时和何处的详细解释,请参见MSDN


9
不,静态类永远不会被实例化。既然其中的所有内容都是静态的,那么为什么要想要将其实例化呢? - Jon Skeet
2
一个 static 类根本没有实例。 - SLaks
4
抱歉,我不理解...我说只创建了一个实例,你不能再新建一个。当然,只有创建了一个静态实例,否则代码就无法调用? - Dave Arkley
2
一个静态类确实有两个实例,但它们不是该类型的实例。静态类将作为[Foo]类型对象(JIT的方法查找表等)和用于初始化的特殊System.Type对象存在于堆上。 - mccainz
一个类可以被声明为静态,表示它只包含静态成员。使用 new 关键字创建静态类的实例是不可能的。当程序或命名空间包含该类被加载时,静态类会被 .NET Framework 公共语言运行时(CLR)自动加载。 - Satheesh

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