2016-11-05 5 views
0

すべてがdelegateが関数ポインタであることを知っています。だから私たちがイベントで作業するときに代理人を宣言しますが、私はイベントの作業の際にデリゲートを宣言しなければならない状況を知りたいのですがpublic delegate void OnButtonClickDelegate();C#イベントを扱うときに明示的なデリゲート宣言が必要な場合は、

ここで私は組み込みデリゲートで使うことができるコードサンプルを参照しています代理人を明示的に宣言する代わりにEventHandlerイベントでの作業時に構築されたデリゲートでEventHandlerは、我々は必要明示的にデリゲートを宣言しないように私の目的を解決するよう

public class ArgsSpecial : EventArgs 
{ 
    public ArgsSpecial (string val) 
    { 
     Operation=val; 
    } 

    public string Operation {get; set;} 
} 

public class Animal 
{ 
    // Empty delegate. In this way you are sure that value is always != null 
    // because no one outside of the class can change it. 
    public event EventHandler<ArgsSpecial> Run = delegate{} 

    public void RaiseEvent() 
    { 
     Run(this, new ArgsSpecial("Run faster")); 
    } 
} 

Animale animal= new Animal(); 
animal.Run += (sender, e) => Console.WriteLine("I'm running. My value is {0}", e.Operation); 
animal.RaiseEvent(); 

。代理人を明示的に宣言しなければならない場所を教えてください。EventHandlerは私たちの目的を解決できないかもしれません。ありがとう

答えて

1

EventHandlerは実際には非常に限定された署名を持ちます。最初のパラメータは常にobjectで、2番目のパラメータはSystem.EventArgsを継承するクラス型でなければなりません。しかし、System.Action<T, ...>System.Func<T, ..., TReturn>を考えると、別のものを宣言する必要は非常にまれです。実際、元のBCLデリゲートタイプMethodInvoker,Converter<T, U>,Predicate<T>、さらにはEventHandler<T>も、その時点でActionファミリとFuncファミリが存在していた場合、定義されていない可能性があります。

依頼者が依頼する参照パラメータが必要な場合は、依然として独自の代理人を宣言する必要があります。 refoutキーワードは、ジェネリック型パラメータを通過することはできませんので、あなたがTryParse家族に一致するデリゲートをしたい場合、あなたはFunc<string, out T, bool>を言うことができないだろうし、それが非常に珍しいのカスタム宣言

/* return true if parsing successful */ 
delegate bool TryParser<T>(string from, out T into); 

が必要になりますイベントで参照パラメータを使用するため、イベントタイプとして使用するデリゲートを宣言する必要はないでしょう。あなたが例えばEventHandler

で指定されたものよりも、パラメータの他人を受け取るイベントをしたい場合には、カスタムデリゲートを必要

+0

と表現することができます。これは、カスタム代理人を使用する必要がある場合の表示コードです。ありがとう – Mou

0

、あなたのAnimalクラスがイベントに別のAnimalがそれを食べてみましたたびに高めるために望んでいると仮定し、このイベントは、捕食者と攻撃されている動物の両方を送る必要があるかもしれません。 Action<>代表団の導入によりものの

public delegate void AttackedDelegate(Animal predator, Animal victim); 
//... 
public event AttackedDelegate OnAttacked; 

:あなたは両方の動物のラッパーとして新しいクラスを作成し、イベントパラメータとしてのインスタンスを送信する必要がありますEventHandlerで、それはデリゲートと簡単です私は、読みやすさ以外の理由から自分自身を宣言する必要があることはあまり一般的ではないと思います。上記の例は、

public event Action<Animal, Animal> OnAttacked; 
+0

私はいくつか理解していますが、 "あなたは、EventHandlerで指定されたもの以外のパラメータを受け取るイベントを必要とする場合には、カスタムデリゲートが必要です。ありがとう – Mou

+0

@Mouは例を編集しましたが、構文はチェックされていませんが、アイデアが明確であることを願っています – KMoussa

関連する問題