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

k; エラーメッセージがわかりました。サンプルコードでは、次のようになります。

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

これは、実際のコードでOnTimedEventは、次のことを示唆しています。staticこれは、メッセージ(コメント)を受け取る理由を説明しています。

非静的フィールド、メソッド、またはプロパティにはオブジェクト参照が必要です'TimerTester.Form1.sData.volume

それで; 最初の問題は、OnTimedEventそうすべきではないということstaticです。これは、イベントサブスクリプションが次のようになることを意味します。

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

または単に:

ret.aliveTimer.Elapsed += ret.OnTimedEvent;

でも!構造体のイベントサブスクリプションは...危険です。構造体のコピーセマンティクスにより、構造体をイベントソースまたはサブスクライバーとして正しく使用することは事実上不可能になります。sData明らかに「値」ではないので、単に:であってはなりません。 struct:である必要がありclassます。疑問がある場合はclass、シナリオの99.99%をカバーします。非常にまれであり、正しく使用された場合structそれが「好きだが安い」という意味であると考える人よりもさらにまれです(これはそれが意味することではありません)。structclass

また、の多くの機能sData(名前、パブリックフィールドの使用、公開された実装の詳細など)を変更しますが、これは2つの大きな問題の二次的なものです。

  • の使用に関する混乱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 に答える