web-dev-qa-db-ja.com

非静的メンバーにアクセスするには、オブジェクト参照が必要です

タイマーがあり、タイマーコールバックを別の関数に入れたいのですが、このエラーが発生します。

オブジェクト参照は、非静的フィールド、メソッド、またはプロパティにアクセスするために必要です '' ...

これらのコールバックをデリゲートイベントとして宣言し、メンバー変数を静的として宣言すると、正常に機能します。そのままにしておくべきですか?

class MainClass
{
    private Timer _timer = null;
    private TimeSpan _millisecs;

    public static void Main (string[] args)
    {
        Application.Init();
        MainWindow win = new MainWindow();

        Label lbl = new Label();
        lbl.Text = "00:00";

        Table tbl = new Table(2, 2, true);
        tbl.Name = "tbl";

        Button btn = new Button("Start");
        tbl.Attach(lbl, 0, 2, 0, 1);
        tbl.Attach(btn, 0, 1, 1, 2);
        Button btn_stop = new Button("Stop");
        tbl.Attach(btn_stop, 1, 2, 1, 2);

        btn.Clicked += StartClick;
        btn_stop.Clicked += StopClick;

        win.Add(tbl);
        win.ShowAll();

        Application.Run ();
    }

    private void StartClick(object obj, EventArgs args)
    {
        if (_timer == null) {
            _timer = new Timer();
            _timer.Elapsed += delegate(object sender, ElapsedEventArgs e) {
                _millisecs = _millisecs.Add(new TimeSpan(0, 0, 0, 0, 50));
                lbl.Text = new DateTime(_millisecs.Ticks).ToString("ss:ff");
            };
            _timer.Interval = 50;
            _timer.Enabled = true;                  
        }

        _timer.Start();             
    }

    private void StopClick(object obj, EventArgs args)
    {
        _timer.Stop();          
    }

}
13
user360330

何をしようとしているのかによります。 どちらか物事を静的にすることができますまたはインスタンスを作成できます:

MainClass instance = new MainClass();
btn.Clicked += instance.StartClick;
btn_stop.Clicked += instance.StopClick;

これはあなたのrealアプリケーションではないので、実際のコードで何をすべきかを言うのは難しいと思います。個人的には、インスタンスの作成に傾いています-静的変数は、通常悪いアイデア(テスト容易性などの点で)であるグローバル状態を表します。しかし、それがあなたの状況に影響するかどうかはわかりません。

重要なのは、理解できることですwhyエラーメッセージが表示され、上記の変更によって修正される理由です。それを理解すると、最良の決定を下すためのより良い状況になります。

23
Jon Skeet

この場合、静的から非静的メソッドにアクセスしているためです。

クラスのオブジェクトを作成し、メソッドを呼び出す

ObjectOfClass obj = new ObjectOfClass();
obj.MethodName();

あなたの場合

MainClass obj = new MainClass();
btn.Clicked += obj.StartClick;
btn_stop.Clicked += obj.StopClick;

または、呼び出されたメソッドを静的として作成します(既に述べたように試しました)。

1
Pranay Rana