3

I know people have asked about this question before but the scenario's were too specific and I am confused about the fundamentals.

I have two basic versions of a C# program, one that works, and one that doesn't. I would love it if someone could please explain why I get the error An object reference is required for the nonstatic field, method, or property in the second program.

Works:

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)
                ;
        }
    }
}

Does not work:

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)
                ;
        }
    }
}

When I try to Print() the text from the Test() class in the second program, it gives me that error An object reference is required for the nonstatic field, method, or property, and I don't understand why. I can see it has to do with where I declare an instance of the Test() class, but I don't remember anything like this happening in C++, so it mystifies me.

What's going on?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Simflare
  • 39
  • 1
  • 1
  • 3

2 Answers2

4

It is not because of the definition of the class, it is all about the usage of keyword static.

The newTest object of the class Test is a public member of the class Program and the main is a static function inside the program class. and it is clearly mentioned in the error message An object reference is required for the non-static method. So what you need is Declare the newTest object as static in order to access them in static methods like main.

like this

 public static Test newTest = new Test();

An Additional Note

Consider that you ware defining the method Print as static inside the class Test as like the following:

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

Then you cant call the method like what you are currently using(newTest.Print();). Instead of that you have to use Test.Print();, Since A static member cannot be referenced through an instance. Instead, it is referenced through the type name. For example, consider the following class

sujith karivelil
  • 28,671
  • 6
  • 55
  • 88
  • Isn't creating variables static a bad practice, except in exceptional circumstances, just like – Simflare Oct 20 '16 at 06:35
  • continued previous - just like global variables are discouraged in C++? – Simflare Oct 20 '16 at 06:36
  • I don't think usage of static variables is a bad practice, you can use if it is needed. but i don't prefer static variables in web applications since they have application scope there – sujith karivelil Oct 20 '16 at 06:42
  • Ok. Thank you very much, you've been very helpful :) – Simflare Oct 20 '16 at 06:58
  • 1
    This answer is not a very good explanation of "why". It explains how to resolve the error but it doesn't explain the error. Nothing is "clearly" mentioned in the error. The error leads you to believe there is a missing reference somewhere (whatever that is), not that the method should be static. – dsanchez Jul 31 '19 at 23:59
1

In the first program you have created a new instance inside a static method. Inside this method it's OK to do anything.

But when you want to call some methods or access some variables outside of static methods, you need them to be static. The reason is when you call a static method, no instance of a class is made and consequently no instance of non-static variables are made yet and you have no access to them!

So, in the second program the newTest variable initiation line is not executed until you have some line of code outside of Program class like Program p = new Program();. The solution is you make the variable static to be able to access it outside of the static Print() method, Or you can convert your Min() method to non-static mode which is impossible for Main() method exceptionally.

If you want to define a global variable, then I suggest you to define a special class 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
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Amin
  • 221
  • 3
  • 13
  • Thank you that is a helpful explanation. This is a bit different to how I'm used to using the word static in C++. Wouldn't creating a static variable be discouraged though, just like global variables are discouraged in C++? – Simflare Oct 20 '16 at 06:37
  • I edited my answer to show some way for defining global variables in C#. Please check my answer again. I hope to be useful for you. – Amin Oct 20 '16 at 09:37
  • Thank you for taking the time to share that :) – Simflare Oct 20 '16 at 10:00