var isSet = a.Event == null; //why is this not allowed! I can not understand
なぜ許可されていませんか?それはevent
であるため、delegate
ではありません。
event
は、制約付きのデリゲートに過ぎません。
イベントのような代理人を扱うことができるようになるまで、私は数年間C#をコーディングしていました。具体的には、任意の数のサブスクライバを1つのデリゲートにアタッチおよびデタッチできます。
次のコードは、これを示しています。
using System;
public class A
{
public event Action Event;
// You could just use System.Action, but I want the example to be clear
public delegate void HandlerDelegateType();
public HandlerDelegateType PublicDelegate;
public void Fire()
{
if(PublicDelegate != null)
{
PublicDelegate();
}
}
}
public static class MainClass
{
public static int Main(string[] args)
{
var a = new A();
if(a.PublicDelegate == null)
{
Console.WriteLine("a.PublicDelegate is null");
}
a.PublicDelegate +=() => { Console.WriteLine("First handler fired!"); };
a.PublicDelegate +=() => { Console.WriteLine("Second handler fired!"); };
a.Fire();
if(a.PublicDelegate != null)
{
Console.WriteLine("a.PublicDelegate is not null");
}
return 0;
}
}
ログ出力が
a.PublicDelegateが解雇
ヌルまずハンドラです!
2番目のハンドラが起動しました!
a.PublicDelegateはevent
キーワードを使用することにより
nullでなく、明示的にそれを使用することができる方法を制限しています。
メンバーへのアクセス方法を制限することは、オブジェクト指向設計の重要な側面です。これは、デザイナーに、あなたのクラスがどのように使われるかについて意見を述べることができます。 C#はあなたにこの機能を提供しますが、喜んでそれに同意できず、イベントではなくデリゲートを公開します。
ここで、「制約付きのデリゲート」という表現は単純すぎることを認めます。 そのようにあなたが実際に、基本となるデリゲートへのパブリックインタフェースとしてイベントを公開することができます:ここであなたを助けて糖衣構文の全体の多くがありますので、C#は、あなたがこれを行うことはできません
private HandlerDelegateType _privateDelegate;
public event HandlerDelegateType PublicEvent
{
add
{
_privateDelegate += value;
}
remove
{
_privateDelegate-= value;
if(_privateDelegate == null)
{
// Can perform some other action here
// For example, unsubscribe from a second event source
}
}
}
@phoog、私は –
ああ、大丈夫、あなたの編集後に、それはより多くを作ることを編集し、私は十分に明確だと思いましたセンス。私はこれが重複していると確信していますが、答えを探す時間がありません。私が正しく思い出した場合、Eric Lippertは数年前にC#チームが自分が選んだイベントパターンを選んだ理由を議論する長い答えを書きました。 – phoog
私はそれを見て、私はそれを見つけることができませんでした –