3

RESOLVED: Dev Env issue. Restarted Dev Env and all OK.

First time asking, so please let me know if I'm doing this wrong.

I'm trying to wrap my head around using instance specific vars in C#. The following test code seems like it should work, but throws an error:

An object reference is required for the non-static field, method, or property...

What is the correct way to do this so that I have a public var that is unique to each instance of the class, and can set that var within a function (static or otherwise)?

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

namespace AlchemyWebSocketsTest2
{
    class KHandler
    {
        public string name = "wut";
        static void KHandlerInstantiate()
        {
            name = "huh";
            Console.WriteLine("All Good.");
        }

    }
}
Darren
  • 68,902
  • 24
  • 138
  • 144
HowDoIDoComputer
  • 1,383
  • 1
  • 10
  • 19
  • 1
    There are many good discussions on similar topic to help out those new to OOP. For example, here's one with some food for thought http://stackoverflow.com/q/290884/471129 . – Erik Eidt Dec 06 '12 at 17:39
  • Thanks Erik :) Still learning how to ask questions clearly here. I'm trying to instantiate this class from a parent class and assign the var within that instance. Question edited. – HowDoIDoComputer Dec 06 '12 at 17:49
  • ok, i added an answer with constructors; maybe that will help get to the right question? – Erik Eidt Dec 06 '12 at 17:59
  • If this has been resolved, can you accept an answer? Or add an answer and accept it. – Ryan Gates Dec 06 '12 at 19:47
  • I added a few more comments and code to my answer. I think that sometimes its hard to find the right language to ask the right question, which is why I'm sticking with it and trying to help.. – Erik Eidt Dec 06 '12 at 21:58

4 Answers4

6

You need an instance of KHandler. Note the handler object which is an instance of the KHandler class.

namespace AlchemyWebSocketsTest2
{
   class KHandler
   {
     public string name = "wut";
     static void Main()
     {
        KHandler handler = new KHandler();
        handler.name = "huh";
        Console.WriteLine("All Good.");
     }

  }
}
Darren
  • 68,902
  • 24
  • 138
  • 144
  • Thanks Darren. What happens if I want to create instances of this class in a parent class? Wouldn't the new instance in Main() then cause problems? – HowDoIDoComputer Dec 06 '12 at 17:47
  • Main() is a starting point of the application, there is only one and you can't have multiple instances of a static method. I would rename KHandler to Program (the default implementation) and then have a separate KHandler class and seperate classes that can be parents/children classes of KHandler. – Darren Dec 06 '12 at 17:51
  • Thanks again Darren. That's more or less what I was doing, I just didn't know that Main() was starting point for whole application instead of just individual classes. Going to go look up how to properly create instantiation method in classes now. Derp. Thanks! – HowDoIDoComputer Dec 06 '12 at 17:53
0

You're trying to access a non-static member inside of a static function. If you declare name as public static string name = "wut";, then your code should compile. I would suggest taking a look at static classes and methods.

PiousVenom
  • 6,888
  • 11
  • 47
  • 86
0

You're trying to assign non static (instance) member in static (type) method. To assign name you have to create instance of he KHandler class

static void Main()
{
     var khandlerInstance = new KHandler();
     khandlerInstance.name = "huh";
     Console.WriteLine("All Good.");
}

UPD. If you need to assign a variable for each instance through the static method, you have to pass the instance as parameter.

class KHandler
{
    string Name;
    public static void ChangeName(KHandler targetInstance, string newName)
    {
        targetInstance.Name = newName;
    }
}
Oleg
  • 1,100
  • 2
  • 11
  • 16
0

Ok, how about a few constructors?

// a sample base class
class KBase  {
     public readonly int value;  // making it readonly means it can only be assigned to once, and that has to happen during a constructor.
     public KBase ( int startValue ) { value = startValue; }
}

class KHandler : KBase
{
    public readonly string name = "wut";

    // this is a parameterless constructor, whose implementation invokes another constructor ( the one below ) of this class
    public KHandler () : this ( "huh" ) {
    }

    // this is a 1 parameter constructor, whose implementation ensures KBase is properly initialized, and then proceeds to initialize its part of the new instance.
    public KHandler ( string val ) : base ( 3 ) { 
        name = val;
    }
}

class Test {
    static void Main()
    {
        // this next line calls the parameterless constructor I defined above
        KHandler handler = new KHandler();  

        // and this next line calls the 1 parameter constructor
        KHandler handler2 = new KHandler("something else");

        Console.WriteLine("All Good 1"+handler.name);
        Console.WriteLine("All Good 2"+handler2.name);
    }
}

I think you want the basic mechanism of constructors, which are run in slightly special environment after the new class instance is allocated and "zeroed". The special environment is that the compiler/language ensure that all the base classes and fields are properly initialized, and, you're allowed to assign to readonly members (only) during construction.

Constructors can call base class constructors to get those bases properly initialized; constructors can also invoke another constructor of the same class before they proceed.

You can have more than one constructor per class -- like in my example above. If you don't specify a constructor, then the compiler effectively inserts a blank parameterless constructor for you. If you don't want this behavior, then adding your own constructor (of any parameter list) cancels the automatic creation of the blank parameterless constructor by the compiler/language. (If you added your own parameterized constructor and still want the parameterless constructor too, you have to add it back yourself.)

The first constructor (the parameterless one) is called as a result of the first new KHandler() and the second one is called by the second new KHandler (string).

Once constructed, an object is considered ready for use. Anyway, search on the general construct of constructors and you'll get more information.

Erik Eidt
  • 23,049
  • 2
  • 29
  • 53
  • Thanks Eric! So maybe my question should be: "If I had another class that contained Main(), and KHandler was a child class that I wanted to instantiate, and I wanted the instantiation function of that class to initialize an instance specific local var, how would I do that?" – HowDoIDoComputer Dec 06 '12 at 18:07
  • ok, one thought is that this is starting to sound like a question that might lead to the factory pattern (http://en.wikipedia.org/wiki/Factory_pattern), or, perhaps to dependency injection (http://en.wikipedia.org/wiki/Dependency_injection). Let me know if we're getting warmer or colder ;) – Erik Eidt Dec 06 '12 at 18:17
  • and some questions on your question: which class is the one you're referring to as "(function of) that class (to initialize)" above, the base or child? and also what is the instantiation function (is it Main?) – Erik Eidt Dec 06 '12 at 18:20
  • Thanks Eric :) Let me try this again, with better signal to noise: I'm really just trying to do this as a simple test, coming from an ECMA background (AS3). Not ready for complex design patterns just yet :) I just wanted to create a class that I can instantiate and have its constructor set its vars. – HowDoIDoComputer Dec 06 '12 at 18:42