C # Variable Scope останавливает меня в моих треках - PullRequest
2 голосов
/ 23 декабря 2011

Я довольно новичок в программировании.Постоянная проблема, с которой я сталкиваюсь, когда пытаюсь что-то для себя на языках C, - это область.

Есть ли способ использовать или изменить переменную из другого метода или класса?Есть ли способ сделать это без создания нового экземпляра класса или объекта?Кажется, что каждый раз вытирает планшет.

Например, я настраиваю консольную текстовую игру и хочу, чтобы через определенные интервалы в консоль записывалось другое фоновое сообщение.

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

Но я не могу заставить разные сообщения играть.Если я создаю переменную из метода, она будет отправлять эту переменную в ее значение по умолчанию при каждом запуске.Если я создаю новый экземпляр объекта или класса, он также отправляет вещи обратно в дефалт.Кроме того, я не могу модифицировать отдельный класс, когда я все время создаю их новые экземпляры.

Это только один пример того, где возникла проблема.Есть ли способ получить Varable с более широкой областью применения?Или я думаю об этом неправильно?

edit:

Проще говоря, можно ли прочитать или изменить переменную из другого метода или класса?

, используяСистема;

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

            int number = 2;
            other();
        }


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

    }
}

Ответы [ 2 ]

2 голосов
/ 23 декабря 2011

Хотя я не думаю, что полностью понял ваш вопрос, вы можете увидеть здесь несколько способов заставить переменную «сохраняться» вне метода:

Статические переменные

Статические переменные - это что-то вроде глобальной переменной.Вы можете видеть их через во всей программе , если вы установите их как общедоступные (если вы установите их как внутренние, они разные).

Статическая переменная может быть определена как:

class MyClass
{
    static int MyVariable = 4;
}

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

Как видите, вы можете получить к ним доступ в любом месте.

Переменные в куче

Если вы создаете объект с new оператор, если вы сохраняете ссылку на этот объект, все изменения, которые вы делаете для него, отражаются на всех ссылках на этот объект, которые у вас есть.Например,

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

Вы даже можете использовать refs для редактирования переменных внутри метода

По сути, вы неправильно поняли концепцию "scope", потому что вы спрашиваете "какие типы переменных существуют "(глобальные / статические / локальные и т. д.).Что вы хотели бы знать о области видимости, так это: локальная переменная существует только в пределах {}, где она определена.

Надеюсь, это даст вам некоторые рекомендации.Ответ определенно не полный, но он может дать вам представление.

Попытайтесь быть более конкретным, чтобы я мог изменить свой ответ.

Ответ для редактирования 1:

Нет, вы не можете изменить переменную так, как хотите, вы должны добавить ее к классу (в данном случае - Программе), попробуйте добавить:

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

Очевидно, что вы должны удалить однувнутри метода Main.

Также обратите внимание, что int нельзя изменить (кроме как без ссылки) внутри функции, если вы передаете их как параметры, потому что они копируются.

Причина довольнопросто: ссылка на экземпляр класса имеет (по крайней мере) тот же размер, что и int (если мы говорим о 32/64-битных системах), поэтому для его копирования или ссылки на него требуется одно и то же время.

Если хотите, вы можете вернуть значение из метода после того, как вы выполнили вычисления, например:

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

int DoSomethingWithX(int x)
{
    x += 30;
}
0 голосов
/ 23 декабря 2011

Модификаторы доступа к классам позволяют вам контролировать членов, которые вы хотите, чтобы класс выставлял другим классам. Кроме того, статический класс с одноэлементным шаблоном позволяют использовать один и тот же экземпляр в вашем приложении.

Глядя на ваш пример, кажется, что вы просто пытаетесь прочитать члена класса, поэтому должно быть достаточно открытого свойства в вашем классе. Экземпляр этого класса может быть передан при инициализации класса, в котором присутствует ваш метод OnTimedEvent (этот метод должен быть изменен на метод экземпляра для доступа к нестатическим членам вашего класса).

Например,

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;
             ...
        }
    }        
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...