0

我有以下结构

private struct sData{
    public int volume;      
    public System.Timers.Timer aliveTimer;
    public void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        Console.WriteLine("this = " + volume);// I cannot access volume here
    }
}

当时间过去了我想改变音量值并且我无法在 OnTimedEvent 中访问它我使用这个代码来启动结构和计时器:

sData ret = new sData();
ret.volume = rand.Next(1, 10) * 100;    
ret.aliveTimer = new System.Timers.Timer(1000);
ret.aliveTimer.Elapsed += new ElapsedEventHandler(sData.OnTimedEvent);
ret.aliveTimer.Start();

我应该怎么办?

4

2 回答 2

2

ķ; 我现在明白错误信息了。在您的示例代码中,您有:

ret.aliveTimer.Elapsed += new ElapsedEventHandler(sData.OnTimedEvent);

这表明在您的真实代码中OnTimedEventstatic- 这解释了您收到消息的原因(评论):

非静态字段、方法或属性“TimerTester.Form1.sData.volume”需要对象引用

所以; 最初的问题是OnTimedEvent不应该static。这反过来意味着事件订阅将是:

ret.aliveTimer.Elapsed += new ElapsedEventHandler(ret.OnTimedEvent);

或者简单地说:

ret.aliveTimer.Elapsed += ret.OnTimedEvent;

然而!结构上的事件订阅是……有风险的。结构的复制语义使得几乎不可能将它们正确地用作事件源或订阅者。sData显然不是一个“值”,所以它根本不应该是 a struct:它应该是 a class。如果您有任何疑问,请class涵盖 99.99% 的场景。struct非常罕见,如果使用得当,甚至罕见,而不是认为这意味着“像但更便宜”的人(这不是它的意思)。structclass

我还会更改许多特性sData(包括名称、公共字段的使用、公开的实现细节等)——但这是两个大问题的次要问题:

  • 使用混淆struct
  • 使用混淆static
于 2012-06-07T08:03:13.980 回答
1

我会将其重写为:

private class Data{
    public int Volume {get; set; }      
    private System.Timers.Timer _aliveTimer;

    public Data() 
    {   
        _aliveTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
    }

    public void Start() 
    {
        _aliveTimer.Start();
    }

    private void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        Console.WriteLine("this = " + volume);
    }
}

Data ret = new Data();
ret.Volume = rand.Next(1, 10) * 100;    
ret.Start();

使用类总是比结构更好的主意。Furthurmore Data 包含一个计时器,但您正在从另一个组件设置 OnTimedEvent 处理程序(在 Data 中定义)。有点不合逻辑。

于 2012-06-07T07:53:37.680 回答