2011-06-20 47 views
6

我需要更多地瞭解代表和C#語言設計。如何獲取委託調用的結果列表?

讓說,我有一個MulticastDelegate實現泛型委託幷包含幾個電話:

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

現在,這個代碼將返回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是不通用的,當代表們」,因爲1.1 MulticastDelegate已經在框架中,這意味着當它被編碼有不提供任何仿製藥。 – Will

回答

2

如果您不使用Func<int>,則可以完成所需操作,但是可以使用一個Action作爲處理返回值的參數。這裏是一個小例子:

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

我現在得到我想要的Listof委託(用「GetInvocations」來轉義所有東西)但你的樣本給了我更多的想法。謝謝。尼斯的思維方式。 –

6

不,沒有更好的方法 - 當您調用多播委託時,結果只是最終委託的結果。這就是框架級別的情況。

多播代表主要是對事件處理程序很有用。將它們用於這類功能比較少見。

請注意,Delegate本身不是通用的 - 只有個人委託類型可以是通用的,因爲類型的arity可以根據類型改變。 (例如,Action<T>Action<T1, T2>確實是不相關的類型。)

+0

MulticastDelegate是抽象的,所以我正確地理解具體的委託像行動「某處裏面」產生繼承類(MulticastDelegate的孩子)?那麼爲什麼不可能添加新方法GetTypedInvocations而不是委託[]而是動作 []? –

+0

@Roman:是的,每種特定類型都可以添加自己的那種方法 - 儘管它需要創建相關的數組等等。 –

1

沒有辦法獲得a)例外情況b)僅從委託人返回值,只能通過嗅探結果列表。另一種方法就是擁有代表名單並手動管理。