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
是 仍然是一个空引用 ,因为你从来没有给它分配任何对象。
ti1
和 tim
不是同一个引用。 如果你把 (=
) 的东西赋值给一个,它不影响另一个。
可能的解决方案
而不是将 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();
}
}
我有这个代码:
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
是 仍然是一个空引用 ,因为你从来没有给它分配任何对象。
ti1
和 tim
不是同一个引用。 如果你把 (=
) 的东西赋值给一个,它不影响另一个。
可能的解决方案
而不是将 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();
}
}