2011-06-20 17 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)仅从委托人返回值,只能通过嗅探结果列表。另一种方法就是拥有代表名单并手动管理。