2

I'm fairly new to programming. The the constant issue I keep facing when I try anything for myself in C based languages is the scope.

Is there any way to use or modify a variable from within a different method or class? Is there also a way to do this without creating a new intance of a class or object? It seems to wipe the slate clean every time.

Example, I'm setting up a console text game, and I want a different background message to write to the console at certain intervals.

public static void OnTimedEvent(object scource, ElapsedEventArgs e) 
{   
    if(Exposition.Narration == 1)
    {
        Console.WriteLine("The bar is hot and muggy");
    }   

    if (Exposition.Narration == 2)
    {
        Console.WriteLine("You see someone stealing beer from the counter");
    }

    if (Exposition.Narration == 3)
    {
        Console.WriteLine("There is a strange smell here");
    }
}

But I have no way of making different messages play. If I create the variable from within the method it will send that variable to its defult everytime it runs. If I create a new instance of an object or a class, it sends things back to the defult as well. Also, I can't modify a single class when I'm creating new instances of them all the time.

That's just one example of where its been a problem. Is there a way to have a varable with a broader scope? Or am I thinking about this the wrong way?

edit:

To put it simply can I read or change a variable from within a different method or class?

using System;

namespace Examp
{
    class Program
    {
        public static void Main(string[] args)
        {

            int number = 2;
            other();
        }


        public static void other()
        {
            if (Main.number == 2)
            {
                number = 3
            }
        }

    }
}
Brad
  • 21
  • 2
  • I don't understand very well you question, You put an example where Exposition.Narration is not defined anywhere and you talk about scopes. You are missing some code to make us understand what you want. Also think about using a switch for that type of code (this is offtopic) – Francesco Belladonna Dec 23 '11 at 02:42
  • Ah, sorry. The general question was more important than the specific example, that's why I was a bit light on detail, I'll make an edit. – Brad Dec 23 '11 at 02:48
  • You can change a variable from another class either by accessing the instance property (you need to pass a reference to the instance) or by accessing the static property of the class (access the class directly, instance is not required). – Devendra D. Chavan Dec 23 '11 at 03:07

2 Answers2

2

While I don't think I understood completely your question, you can see here some ways to make a variable "persist" outside a method:

Static variables

Static variables are something like a global variable. You can see them through all the program if you set them as public (if you set them as internal, it's different).

A static variable can be defined as:

class MyClass
{
    static int MyVariable = 4;
}

....somewhere...
void MyMethod()
{
    MyClass.MyVariable = 234;
}

As you can see, you can access them anywhere.

Variables on heap

If you create an object with new operator, if you keep reference to that object, every modify you do on it, it reflects on all references to that object that you have. For example

class MyClass
{
    int X;
}

static class Program
{
    static void Main(string args[])
    {
        MyClass a = new MyClass();
        a.X = 40;
        Method1(a);
        Method2(a);
        Console.WriteLine(a.X.ToString()); // This will print 32
    }

    static void Method1(MyClass c)
    {
        c.X = 10;
    }

    static void Method2(MyClass c)
    {
        c.X = 32;
    }
}

You can even use refs to edit your variables inside a method

Basically you misunderstood the concept of "scope", because you question is "which variable types exist" (global/static/local etc.). What you would like to know about scope is this: A local variable exists only within { } where it's defined.

I hope this gives you some suggestion. The answer is definitely not complete but can give you an idea.

Try to be more specific so I can change my answer.

Answer to edit 1:

No you can't change a variable in the way you want, you must add it to the class (Program in this case), try adding:

class Program
{
    static int number;
    ....
}

Obviusly you should remove the one inside the Main method.

Also note that int can't be modified (except without a ref) inside a function if you pass them as parameters because they are copied.

The reason is quite simple: a reference to a Class instance is (at least) the same size as an int (if we are speaking about 32/64 bit systems), so it takes the same time copying it or referencing it.

You can return a value from a method after you have done your calculations if you want, like this:

int x = 3;
x = DoSomethingWithX(x);

int DoSomethingWithX(int x)
{
    x += 30;
}
Francesco Belladonna
  • 11,361
  • 12
  • 77
  • 147
  • Ah, yes thanks I think you have answered my question. I wasn't able to use anything other than a local variable. I tried the former suggestion (MyClass.MyVariable = 234;) but I think it gave me an error message about creating a new object, something along those lines. It might have been the syntax. Thanks, this is useful. – Brad Dec 23 '11 at 03:07
  • Class instances are [passed by reference](http://stackoverflow.com/questions/2027/pass-by-reference-or-pass-by-value), `ref` keyword is redundant. – Devendra D. Chavan Dec 23 '11 at 03:11
  • @Brad: If you need something else let me know, I can't be more specific because I didn't completely understood what you want. **Didn't see your edit, let me answer in the question**. Devendra: Well I didn't specify why he should use ref for, that's why I put a link to them. – Francesco Belladonna Dec 23 '11 at 03:20
  • 1
    @DevendraD.Chavan but class references can be passed by reference, so `ref` can be useful with reference types, even if it is confusing. – phoog Dec 23 '11 at 04:19
  • Why is a reference guaranteed to be the same size as an int? Is a reference on a 64 bit system guaranteed to be the same size as a 32 bit int, in your understanding? – Eric Lippert Dec 23 '11 at 15:29
  • It's different obviusly, I edited it to specify that is *at least* as an int. It was just to explain him why we are copying ints instead of creating references to them. – Francesco Belladonna Dec 23 '11 at 15:40
0

Class access modifiers allow you to control the members that you want the class to expose to other classes. Furthermore, static class with singleton pattern allow use to reuse the same instance across your application.

Looking at your example, it appears that you are simply trying to read the class member, hence a public property in your class should suffice. The instance of this class can be passed while initializing the class in which your OnTimedEvent method is present (this method should be changed to an instance method to access non static members of the your class).

For example,

class MyClass
{
    private Exposition exposition;

    // Option 1: Use parametrized constructor
    // Pass the instance reference of the other class while 
    // constructing the object
    public MyClass(Exposition exposition)
    {
        this.exposition = exposition;
    }

    // Option 2: Use an initialize method
    public void Initialize(Exposition exposition)
    {
        this.exposition = exposition;
    }

    // Remove static to access instance members
    public void OnTimedEvent(object scource, ElapsedEventArgs e) 
    {   
        // Better to use an enumeration/switch instead of magic constants
        switch(exposition.Narration)
        { 
             case HotAndMuggy:
                 Console.WriteLine("The bar is hot and muggy");;
                 break;
             ...
        }
    }     

    // Option 3: Use static properties of the Exposition class
    // Note this approach should be used only if your application demands 
    // only one instance of the class to be created        
    public static void OnTimedEvent_Static(object scource, ElapsedEventArgs e) 
    {   
        // Better to use an enumeration/switch instead of magic constants
        switch(Exposition.Narration)
        { 
             case HotAndMuggy:
                 Console.WriteLine("The bar is hot and muggy");;
                 break;
             ...
        }
    }        
}
Devendra D. Chavan
  • 8,871
  • 4
  • 31
  • 35
  • Thanks, I'll have to mill it over and look into it more to understand how it works better. I'll keep it close as a reference. – Brad Dec 23 '11 at 03:19