2011-06-20 5 views
6

デリゲートとC#言語の設計についてもう少し詳しく知る必要があります。デリゲートの呼び出しの結果リストを取得するには?

は私がジェネリックデリゲートを実装し、いくつかの呼び出しを含むMulticastDelegateを持っている、としましょう:今、このコードは32を返します

Func<int> func = null; 
func += ()=> return 8; 
func +=() => return 16; 
func +=() => return 32; 

int x = func(); // x=32 

を私はそこかどうかを知りたいですC#言語機能は、すべてのデリゲートの呼び出し結果へのアクセスを取得することができます(つまり、{8,16,32})を取得することを意味しますか?

.NETフレームワークルーチンを使用して同じことを行うことはもちろん可能です。このような何かが作業を行います。

public static List<TOut> InvokeToList<TOut>(this Func<TOut> func) 
{ 
    var returnValue = new List<TOut>(); 
    if (func != null) 
    { 
     var invocations = func.GetInvocationList(); 
     returnValue.AddRange(invocations.Select(@delegate => ((Func<TOut>) @delegate)())); 
    } 
    return returnValue; 
} 

をしかし、私は、少なくともキャストなし(デリゲートがあるときに、本当に、なぜMulticastDelegateはジェネリックではありません)、より良い方法があるはずというシステムから抜け出すことができませんか?

+2

は「代表者がいるときは本当に、なぜMulticastDelegateは、汎用ではありません」。 – Will

答えて

2

Func<int>を使用しない場合、戻り値を処理するパラメータとしてメソッドを使用するアクションを実行できます。ここで小さな例です:MulticastDelegateは、それが利用可能なジェネリックがなかったコード化されたときを意味し、1.1以降の枠組みになっている

static Action<Action<int>> OnMyEvent=null; 

    static void Main(string[] args) 
    { 
     OnMyEvent += processResult => processResult(8); 
     OnMyEvent += processResult => processResult(16); 
     OnMyEvent += processResult => processResult(32); 

     var results = new List<int>(); 
     OnMyEvent(val => results.Add(val)); 

     foreach (var v in results) 
      Console.WriteLine(v); 

    } 
+0

Listen Delegate(GetInvocationsですべてのものをエスケープする)あなたのサンプルは私にさらなるアイデアを与えます。ありがとうございました。いい考え方。 –

6

いいえ、良い方法はありません。マルチキャストデリゲートを呼び出すと、結果は最終デリゲートの結果になります。それはフレームワークレベルでのようなものです。

マルチキャストの代理人は、、ほとんどは、イベントハンドラに便利です。このような関数に使うのは比較的稀です。

Delegate自体は汎用的ではない。なおどちらか - タイプのアリティは、タイプに基づいて変更することができますので、唯一の個々デリゲート型は、一般的なことができます。 (例:Action<T>Action<T1, T2>は実際には無関係の型です)。

+0

MulticastDelegateは抽象ですので、アクションのような具体的な代理人が継承したクラス(MulticastDelegateの子)を生成する "どこかにある"ことを理解できますか?なぜ、Delegate []ではなく、 []を返すために新しいメソッドGetTypedInvocationsを追加することは不可能ですか? –

+0

@Roman:はい、それぞれの特定の型は、そのような独自のメソッドを追加することができます。関連する配列などを作成する必要があります。 –

1

例外を取得する方法はありません。b)結果リストにスニッフィングするだけで、代理人の値を返します。別の方法は、デリゲートのリストを持ち、それを手動で管理することです。

関連する問題