c#变量作用域阻止了我的前进

本文关键字:我的 变量 作用域 | 更新日期: 2023-09-27 18:18:35

我对编程相当陌生。当我在基于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");
    }
}

但是我没有办法让不同的消息播放。如果我在方法中创建变量它会在每次运行时将该变量发送到它的默认值。如果我创建一个对象或类的新实例,它也会将内容发送回默认值。而且,当我一直在创建一个类的新实例时,我不能修改单个类。

这只是其中一个问题的例子。是否有一种方法可以使变量具有更广泛的作用域?还是我想错了?

编辑:

简单地说,我可以从不同的方法或类中读取或更改变量吗?

使用系统;

namespace Examp
{
    class Program
    {
        public static void Main(string[] args)
        {
            int number = 2;
            other();
        }

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

c#变量作用域阻止了我的前进

虽然我不认为我完全理解你的问题,你可以在这里看到一些方法,使一个变量"持久"的方法:

静态变量有点像全局变量。如果您将它们设置为public(如果您将它们设置为internal,则不同),则可以通过查看所有程序

静态变量可以定义为:

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来编辑方法中的变量

基本上你误解了"作用域"的概念,因为你的问题是"存在哪些变量类型"(全局/静态/局部等)。关于作用域,你需要知道的是:局部变量只存在于定义它的{}内。

我希望这能给你一些建议。答案肯定不完整,但可以给你一个想法。

试着更具体一些,这样我可以修改我的答案。

编辑1的答案:

不,你不能以你想要的方式改变一个变量,你必须把它添加到类中(在这个例子中是Program),试着添加:

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

显然你应该删除Main方法中的那个

还请注意,如果将int作为参数传递给函数,则不能在函数内部修改int(除非没有ref),因为它们是复制的。

原因很简单:对Class实例的引用(至少)与int(如果我们谈论的是32/64位系统)的大小相同,因此复制它或引用它所花费的时间相同。

如果需要,可以在完成计算后从方法返回一个值,如下所示:

int x = 3;
x = DoSomethingWithX(x);
int DoSomethingWithX(int x)
{
    x += 30;
}

类访问修饰符允许您控制希望类公开给其他类的成员。此外,具有单例模式的静态类允许在整个应用程序中重用相同的实例。

看看你的例子,看起来你只是试图读取类成员,因此在你的类中的公共属性应该足够了。该类的实例可以在初始化存在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;
             ...
        }
    }        
}