理解C#中的静态(static)关键字

4

我正在学习C#,但是我不太理解static关键字。

假设我有以下代码:

using System;
using System.IO;
using System.IO.Ports;

class PortThing
{
    SerialPort port;

    void InitPort()
    {
        if(!File.Exists("/dev/whatever"))
        {
            System.Console.WriteLine("Device not found.");    
            port = null;  
        }
        //else port = something
    }

    public static void Main(string[] args)
    {
        InitPort();
        System.Console.WriteLine("Done.");
    }
}

据我所理解,静态方法属于类而不是该类的对象。因此,静态方法不能引用非静态方法/字段,因为它们需要实例化一个类。
编译器抱怨 Main() 调用 InitPort() 并希望将其变为静态方法。 我可以这样做,但这需要使 port 成为静态字段。按照这种思路,一切都会变成静态。
我哪里理解错了?
5个回答

10

您做得很对。静态方法只能访问静态成员,非静态成员需要类的实例才能访问它们。因此,您可以这样做:

public static void Main(string[] args)
{
    new PortThing().InitPort();
    System.Console.WriteLine("Done.");
}

通过这种方式,您在给定的类实例上调用实例方法InitPort,并且可以使port字段保持非静态状态。


所有静态成员...不仅仅是静态字段。 - Matthew Whited
你的例子与你的解释相矛盾。为什么不重新写第二句话(也许提到非静态成员需要一个实例,静态Main方法没有默认实例,所以必须显式提供一个),然后你就有我的支持了。 - Ben Voigt

3
public static void Main(string[] args)
{
    PortThing pt = new PortThing();
    pt.InitPort();
    System.Console.WriteLine("Done.");
}

2

你没有做错任何事情。

这里的问题是,在普通类中,Main 不需要是 static。但在这里,它需要是静态的,因为它提供了程序的入口点。换句话说,你需要一个方法来运行,但在运行之前你无法创建对象,所以该方法必须是 static

实际上,没有任何阻止你创建 PortThing 类的对象并正常使用它:

public static void Main(string[] args)
{
    var pt = new PortThing();
    pt.InitPort();
    System.Console.WriteLine("Done.");
}

1
你说得对:静态方法属于类而不是对象。
但在这种情况下,如果您不想使所有内容都是静态的,您可以简单地创建一个PortThing类型的对象,换句话说,实例化这个类,并调用非静态方法。
或者,如果该非静态方法不访问任何类属性,至少是非静态属性,您可以将其设置为静态。

0

静态方法和变量可以在没有类实例的情况下使用。

关于静态变量最重要的事情是,每个进程(更准确地说是AppDomain,但大多数进程只有1个AppDomain)只有一个该变量的实例。我认为静态变量就像全局变量一样。您可以创建类的静态构造函数来初始化这些静态变量。当第一次访问该类时,将调用静态构造函数一次。但请注意并发问题,特别是访问和修改静态成员的多线程应用程序,尤其是静态集合!

静态方法可以被视为C中的函数。它们可以在不创建任何对象的情况下调用,这对性能略微更好(但应仅在有意义的地方使用)。例如,我会在静态实用程序类中实现方法int CountNumberOfCommas(string s)作为静态方法,因为这是独立于任何类实例的操作。

您没有做错任何事情。您只需要在两个选项之间进行选择:您可以创建Program的实例并调用InitPort,或使InitPort静态,并且不创建Program的实例。使所有内容都静态本质上与在C中编写程序相同,其中您只定义函数。


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