非静态字段、方法或属性需要对象引用

本文关键字:属性 对象引用 方法 静态 字段 | 更新日期: 2023-09-27 18:13:59

我知道以前有人问过这个问题,但是这个场景太具体了,我对基本原理感到困惑。

我有两个基本版本的c#程序,一个可以工作,一个不能。如果有人能解释一下为什么我得到错误在第二个程序中非静态字段、方法或属性需要对象引用,我将很高兴。

:

namespace Experiments
{
    class Test
    {
        public string myTest = "Gobbledigook";
        public void Print()
        {
            Console.Write(myTest);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Test newTest = new Test();
            newTest.Print();
            while (true)
                ;
        }
    }
}

不工作:

namespace Experiments
{
    class Test
    {
        public string myTest = "Gobbledigook";
        public void Print()
        {
            Console.Write(myTest);
        }
    }
    class Program
    {
        public Test newTest = new Test();
        static void Main(string[] args)
        {
            newTest.Print();
            while (true)
                ;
        }
    }
}

当我在第二个程序中尝试Print()来自Test()类的文本时,它给了我错误非静态字段,方法或属性需要对象引用,我不明白为什么。我可以看出这与我在哪里声明Test()类的实例有关,但我不记得在c++中发生过这样的事情,所以我很困惑。

怎么回事?

非静态字段、方法或属性需要对象引用

这并不是因为类的定义,而是关键字static的使用。

TestnewTest对象是类Program的公共成员,main是程序类内部的静态函数。并且在错误信息An object reference is required for the non-static method中明确提到。因此,您需要的是将newTest对象声明为静态,以便在静态方法(如main)中访问它们。

这样的

 public static Test newTest = new Test();

一个附加注释

考虑在类Test中定义方法Printstatic,如下所示:

 public static void Print()
 {
    Console.Write(myTest);
 }

那么你就不能像你目前使用的那样调用方法(newTest.Print();)。您必须使用Test.Print();,因为静态成员不能通过实例引用。相反,它是通过类型名称引用的。例如,考虑下面的类

在第一个程序中,您在static方法中创建了一个新实例。在这个方法中可以做任何事情。

但是当你想调用静态方法之外的一些方法或访问一些变量时,你需要它们是静态的。原因是当您调用静态方法时,没有创建类的实例,因此还没有创建非静态变量的实例,您无法访问它们!

因此,在第二个程序中,直到在 program 类(如Program p = new Program();)之外有一些代码行,才执行newTest变量初始化行。解决方案是使变量静态,以便能够在静态Print()方法之外访问它,或者您可以将Min()方法转换为非静态模式,这对于Main()方法是不可能的。

如果你想定义一个全局变量,那么我建议你定义一个特殊的类,例如MyGlobals:

public class SomeClass
{
    public int x;
}
public class MyGlobals
{
    public static SomeClass mySharedVariable = new SomeClass();
    public SomeClass myGlobalVariable = null;
}
// Usage:
class Program
{
    static void Main(string[] args)
    {
        MyGlobals.mySharedVariable.x = 10; // Shared among all instances
        MyGlobals myGlobal = new MyGlobals(); // New instance of MyGlobals
        myGlobal.myGlobalVariable = new SomeClass(); // New instance of SomeClass
        myGlobal.myGlobalVariable.x = 10; // One instance of MyGlobals including one instance of SomeClass
    }
}
相关文章: