尝试全局访问变量

Posted

技术标签:

【中文标题】尝试全局访问变量【英文标题】:Trying to access a variable globally 【发布时间】:2011-10-06 09:16:13 【问题描述】:

我有一个迷宫游戏,我正在尝试一次创建两个计时器。 1st(300秒后退出游戏)

t1.Interval = 30000;
t1.Enabled = true;
t1.Elapsed += new ElapsedEventHandler(hiddenTimer);

public static void hiddenTimer(object source, ElapsedEventArgs e)
    
        Console.Clear();
        Environment.Exit(1);
    

2nd(每 1 秒显示一次剩余时间(类似于真正的计时器))

t2.Interval = 1000;
t2.Enabled = true;
t2.Elapsed += new ElapsedEventHandler(showTimer);

public static void showTimer(object source, ElapsedEventArgs e)
    
        Console.Write(timeLeft);
    

我想全局传递声明 timeLeft 但它说“非静态字段、方法或属性需要对象引用...”

如何正确声明?

【问题讨论】:

1 秒 == 1000 毫秒,所以 t1.Interval=300000,加一个 0 请发布您的所有代码。您没有发布 timeLeft 的声明。问题很明显,您尝试在静态方法中使用非静态属性。 我的两个计时器都在工作,但我在显示 2ndTimer 时遇到问题,因为它是一个迷宫游戏,我的光标一直在移动,这就是时间跟随我的光标的原因。有什么建议我该如何解决这个问题? 你写的时间怎么样?你真的在使用 Console.WriteLine 吗? 然后你去写时间的时候,保存当前位置,把位置移动到你想显示时间的地方,写下时间,然后恢复位置。 【参考方案1】:

通过制作静态属性:

public static Double TimeLeft  get; set; 

如果您想从整个上下文中公开访问,如果您希望它是私有的,只需将 public 更改为 private

顺便说一句,内置的Timer 不支持轮询剩余时间,直到下一次过去。您可以在 1 秒计时器上的每个 Elapse 事件中减少 TimeLeft,或者您可以查看 this。

编辑

这是使用一个计时器的一种方法,首先我声明我使用的两个属性和一个常量字段,不要担心它们是静态的,以这种方式将它作为控制台应用程序运行会更容易。

public static Timer SystemTimer  get; set; 
public static double Elapsed  get; set; 

private const double CycleInterval = 1000;

然后在我的Main-方法中,我有以下内容来启动我的Timer

SystemTimer = new Timer();
SystemTimer.Interval = CycleInterval;
SystemTimer.Enabled = true;
SystemTimer.Elapsed += Cycle;

SystemTimer.Start();

有了这个,Cycle-event 处理程序可以如下所示:

static void Cycle(object sender, ElapsedEventArgs e)

    Elapsed += CycleInterval;

    if ((Elapsed%5000) == 0.0)
    
        Console.WriteLine("5 sec elapsed!");
        // Do stuff each 5 sec
    

    if ((Elapsed % 10000) == 0.0)
    
        Console.WriteLine("10 sec elapsed!");
        // Do stuff each 10 sec
    

    Console.WriteLine("Elapsed: 0", Elapsed);

您也可以将Elapsed 设置为TimeSpan,但您可以根据需要对其进行重构。

这是我使用的完整源代码:

using System;
using System.IO;
using System.Timers;

namespace ConsoleApplication5

    class Program
    
        public static Timer SystemTimer  get; set; 
        public static double Elapsed  get; set; 

        private const double CycleInterval = 1000;

        static void Main(string[] args)
        
            SystemTimer = new Timer();
            SystemTimer.Interval = CycleInterval;
            SystemTimer.Enabled = true;
            SystemTimer.Elapsed += Cycle;

            SystemTimer.Start();

            while (true) ;

        

        static void Cycle(object sender, ElapsedEventArgs e)
        
            Elapsed += CycleInterval;

            if ((Elapsed%5000) == 0.0)
            
                Console.WriteLine("5 sec elapsed!");
                // Do stuff each 5 sec
            

            if ((Elapsed % 10000) == 0.0)
            
                Console.WriteLine("10 sec elapsed!");
                // Do stuff each 10 sec
            

            Console.WriteLine("Elapsed: 0", Elapsed);
        
    

这就是我运行它时的样子:

【讨论】:

是的。我已经添加了一个 timeLeft--;在 showTimer() 方法中。我现在的问题是如何写时间。我的光标一直在移动,这是一个迷宫游戏,这就是为什么我的光标会留下时间痕迹!哈哈。我知道这是另一个问题,但如果可以的话,请帮助我。 :D @Reinan,再次更新了我的答案,举了一个关于如何用一个计时器来做的例子,最终可能更容易阅读你的代码,而不是有很多计时器。但请记住,这只是一种方式,使用TimeSpan 也是一种不错的方式。 @Reinan,我不太关注你的另一个问题。如果您最初的问题现在已解决,请将帮助您解决问题的答案标记为已接受。然后用另一个问题创建一个新问题。 @Filip 对不起,我是新来的,我不太习惯这里的工作方式:D 我会发布另一个问题,请稍后看看我的帖子。【参考方案2】:

首先,如果你想让 timeLeft 表现得像一个全局变量,你应该将它声明为一个静态变量。

其次,我会使用一个计时器并分别记录每个事件的时间:

static DateTime startTime = DateTime.Now;
static DateTime lastTime = DateTime.Now;

在您的计时器中,应该将其设置为更精确的值,例如 1/10 秒,请执行以下操作:

if (DateTime.Now - lastTime > new TimeSpan(0, 0, 1))
   // Update the time here for your 1s clock
lastTime = DateTime.Now;

if (DateTime.Now - startTime > new TimeSpan(0, 0, 300))
    // Exit the game

这样你的时间安排会更准确。

【讨论】:

我想怎么做呢?有什么建议吗? @Filip,真有趣,你会很有竞争力地对我的回答发表评论。 这会很有帮助,但我有一个新问题。你能帮我只在一个地方显示时间吗?时间跟随我用来在迷宫内移动头像的光标的轨迹。 @Filip @Ares 你的修改都有效。非常感谢你。如果您能帮我解决另一个问题,我将不胜感激。 :D @AresAvatar,评论已删除,我并没有冒犯的意思,我也做了一个例子。当我看到他写“我该怎么做”时,我已经在 Visual Studio 中做这件事了。【参考方案3】:

标记为静态:

public static int TimeLeft;

【讨论】:

【参考方案4】:

您的timeLeft 成员不是静态

将其设为静态或将showTimer方法设为静态。

问候。

【讨论】:

以上是关于尝试全局访问变量的主要内容,如果未能解决你的问题,请参考以下文章

从匿名函数汇编脚本访问全局变量

如何访问全局变量

使用 C++ 访问 Lua 全局表

不引用全局打字稿就无法直接访问全局变量

sycl/dpc++ 使用全局指针访问全局变量

如何全局访问 AJAX 定义的变量? [复制]