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

时间:2016-10-20 03:41:33

标签: c# class initialization declaration non-static

我知道人们之前已经问过这个问题,但情节太具体了,我对基本面感到困惑。

我有一个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)
                ;
        }
    }
}

当我尝试打印()第二个程序中 Test()类的文本时,它会给我发错需要对象引用对于非静态场,方法或属性,我不明白为什么。我可以看到它与我声明Test()类的实例的地方有关,但我不记得在C ++中发生过这样的事情,所以它让我感到困惑。

发生了什么事?

2 个答案:

答案 0 :(得分:4)

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

newTest的{​​{1}}对象是类Test的公共成员,Program是程序类中的静态函数。并且在错误消息main中提到了它。所以你需要的是将An object reference is required for the non-static method对象声明为静态,以便在像main这样的静态方法中访问它们。

像这样

newTest

附加说明

考虑您在方法 public static Test newTest = new Test(); 中将方法Print定义为static,如下所示:

Test

然后你不能像你当前使用的那样调用方法( public static void Print() { Console.Write(myTest); } )。而不是你必须使用newTest.Print();,因为静态成员不能通过实例引用。相反,它通过类型名称引用。例如,请考虑以下类

答案 1 :(得分:0)

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

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

因此,在第二个程序中, newTest 变量启动行不会执行,直到你有一些代码行在 Program 类之外,如Program p = new Program();。解决方案是让变量静态以便能够在静态 Print()方法之外访问它,或者您可以将 Min()方法转换为非静态方法特殊情况下 Main()方法无法实现的模式。

如果你想定义一个全局变量,那么我建议你定义一个特殊的类e.x. 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
    }
}