C# Winforms 计时器/对象引用未设置为对象的实例

C# Winforms timers / object reference not set to an instance of an object

我有这个代码:

System.Timers.Timer ti1, ti2, ti3;

private void button1_Click(object sender, EventArgs e)
{
   if(_1 == true)
{
    ti1 = new System.Timers.Timer(1000);
    ti1.Interval = 1000;
    ti1.Elapsed += new System.Timers.ElapsedEventHandler(tiel1);
    ti1.Enabled = true;
}
else
{
    ti1.Stop();
}
}

它成功运行,但因为我不想使用相同的代码,所以我创建了一个辅助方法:

private void my_timer(System.Timers.Timer tim, System.Timers.ElapsedEventHandler Tick)
        {
            tim = new System.Timers.Timer(1000);
            tim.Interval = 1000;
            tim.Elapsed += new System.Timers.ElapsedEventHandler(Tick);
            tim.Enabled = true;
        }

然后我称之为my_timer(ti1, tiel1)

但是当调用 ti1.Stop() 时它给了我这个错误 "object reference not set to an instance of an object"。

知道为什么吗? 谢谢

在C#中,参数一般都是传值

这是它的意思。

当您为方法参数分配新值时,如下所示:

tim = new System.Timers.Timer(1000);

意味着从现在开始tim将是一个新的Timer的引用,但它不影响你从外部传递的引用(ti1)。所以在你的例子中 ti1 仍然是一个空引用 ,因为你从来没有给它分配任何对象。

ti1tim 不是同一个引用。 如果你把 (=) 的东西赋值给一个,它不影响另一个。

可能的解决方案

而不是将 tim 声明为参数,您应该 return 来自方法的新对象:

var tim = ...

...

return tim

并将方法的结果赋值给ti1:

ti1 = my_timer( ... )

这是因为在c#方法中参数是按值传递的,而不是按引用传递的。

如果你的代码 System.Timers.Timer ti1, ti2, ti3; 所有 3 个都是包含空值的 System.Timers.Timer 的引用。

当你传递 ti1 作为参数时,它传递了 ti1 的值 null 所以, 执行以下表达式后:tim = new System.Timers.Timer(1000); 它具有 System.Timers.Timer 的引用,而 ti1 仍然包含空值

因此,按照以下方式重新安排您的 my_timer 方法以实现您的预​​期行为

private System.Timers.Timer my_timer(System.Timers.Timer tim, System.Timers.ElapsedEventHandler Tick)
    {
        tim.Interval = 1000;
        tim.Elapsed += new System.Timers.ElapsedEventHandler(Tick);
        tim.Enabled = true;
        return tim;
    }

然后触发方法并使用返回值如下

System.Timers.Timer ti1, ti2, ti3;

private void button1_Click(object sender, EventArgs e)
{
   ti1 = new System.Timers.Timer(1000);
   if(_1 == true)
   {
      ti1 = my_timer(ti1, tiel1)
   }
   else
   {
     ti1.Stop();
   }
}