50873


Main関数部のコメント部なのですが、イベントハンドラー？がnullだったらイベントが設定されていなのでコメント部のようなコードを書くと判明しますと参考書にあるのですがエラーになってしまいそのエラー原因もわからず困っています、教えていただけますでしょうか。？

[イベント 'TestClass.ThreeEvent' は、+= または -= の左側にのみ表示されます (型 'TestClass'
内で使用する場合を除きます) ConsoleApp3  
]

[code]

    using System;
    
    delegate void SampleEventHandler();
    
    class TestClass
    {
        public event SampleEventHandler ThreeEvent = delegate { };
        //public event SampleEventHandler ThreeEvent = () => { };
    
        public void OnThreeEvent()
        {
            for(int i=1; i<=200; i++)
            {
                Console.WriteLine(i);
    
                if(i % 3 == 0)
                {
                    ThreeEvent();
                }
            }
        }
    }
    
    class Program
    {
        public static void Main()
        {
            TestClass t = new TestClass();
    
            t.ThreeEvent += delegate { Console.WriteLine("xx"); };
            /*ここです。*/
            if (t.ThreeEvent != null)
            {
                Console.WriteLine("");
            }
            //t.ThreeEvent += () => Console.WriteLine("xx");
            t.OnThreeEvent();
    
    
            Console.ReadKey();
        }
    }
    
[/code]


CC BY-SA 4.0
2018-12-01T12:37:17.487
50816
2018-12-03T15:19:10.330
2018-12-03T02:08:42.057
29826
question
c#
イベントが設定されてるかどうかを知りたいif文のエラーが原因が知りたい。


[デリゲートとイベント](https://docs.microsoft.com/ja-jp/dotnet/csharp/delegates-
events)は別物です。

[code]

    public event SampleEventHandler ThreeEvent;
    
[/code]

は省略形式であり本来は

[code]

    private SampleEventHandler _threeEvent;  // 実際には_threeEventでなくアクセスできない名前
    public event SampleEventHandler ThreeEvent {
      add { _threeEvent += value; }
      remove { _threeEvent -= value; }
    }
    
[/code]

となっています。イベント`ThreeEvent`は`+=`と`-=`しか行えず、ハンドラ設定の有無はデリゲート`_threeEvent`側を見る必要があります。  
省略形式ではデリゲートには直接アクセスできないため、一旦、デリゲート変数へコピーする必要があります。

[code]

    SampleEventHandler te = this.ThreeEvent;
    if (te != null) {
        ...
    }
    
[/code]


CC BY-SA 4.0
2018-12-03T02:02:48.577
50845
2018-12-03T02:02:48.577
4236
50816
answer


エラーメッセージ(変な日本語ですが)のとおり、イベントに対しては、それを定義したクラス(ここでは`TestClass`)の外では`+=`か`-=`でイベントハンドラの設定/解除を行うことしかできません。

[code]

        if (this.ThreeEvent != null)
        {
            Console.WriteLine("");
        }
    
[/code]

と`TestClass`のメソッドの中で記述してください。

**ちなみに**

掲題のコードは何がしたいのかよくわかりませんが、よくあるのはイベント発火の前にnullチェックするコードです。

[code]

        if (this.ThreeEvent != null)
        {
            this.ThreeEvent();
        }
    
[/code]

厳密にはこれはスレッドセーフではない(ifを通って発火するまでの間にnullになる可能性がある)ので、次にように書く必要があります。

[code]

        var handler = this.ThreeEvent;
        if (handler != null)
        {
            handler();
        }
    
[/code]

これは、C#6(Visual Studio 2015)からは次のように楽に書けます。

[code]

        this.ThreeEvent?.Invoke();
    
[/code]


CC BY-SA 4.0
2018-12-03T15:19:10.330
50873
2018-12-03T15:19:10.330
4765
50816
answer