单独打电话给代表?

时间:2010-12-15 15:10:01

标签: c# delegates

如果我有这样的代表:

 Delegate void Render();
 Render ToRender;

在这里使用它:

 ToRender += FunctionRender;
 ToRender += SomeOtherRender;

如何制作它以便我可以单独调用每个功能?像这样:

 foreach(Render render in ToRender)
 {
     BeginRender();


     render();


     EndRender();
 }

4 个答案:

答案 0 :(得分:11)

您可以使用Delegate.GetInvocationList()分别获取每个。

foreach (Render render in ToRender.GetInvocationList())
{
    ...
}

请注意,GetInvocationList()只会返回Delegate[],但foreach会对每个项目进行隐式转换,这就是上述循环的工作原理。

哦,你应该首先检查ToRender是否null,否则你将获得NullReferenceException。你实际上可以编写一个通用的扩展方法来使这个更好,但是你需要对C#中不允许的委托类型有一个约束:(

如果你不关心缺乏约束,你可以伪造它:

public static IEnumerable<T> GetIndividualDelegates<T>(this T multiDelegate)
    where T : class
{
    if (multiDelegate == null)
    {
        yield break;
    }
    Delegate d = (Delegate)(object) multiDelegate;
    foreach (Delegate item in d.GetInvocationList())
    {
         yield return (T)(object) item;
    }    
}

(由于对通用转换的限制,这很尴尬。)

你可以这样写:

foreach (Render render in ToRender.GetIndividualDelegates())
{
    ...
}

不用担心ToRender是否为空。

答案 1 :(得分:3)

foreach (Render render in ToRender.GetInvocationList())

理想方式:

Render temp = ToRender;

if (temp != null)
{
    foreach (Render render in temp.GetInvocationList())
    {
        BeginRender();

        render();

        EndRender();
    }
}

答案 2 :(得分:1)

ToRender.GetInvocationList返回“list”中包含的所有委托的数组。

答案 3 :(得分:-1)

这不是委托和事件的工作方式。框架将自动调用所有方法。事件处理程序应该能够完全独立于任何其他处理程序执行。如果你需要更紧密地控制流量,你应该考虑重新设计你的方法。

也许是3个事件/代表 - 类似于asp.net的方式。 PreRender,Render和PostRender。我不确定你在做什么,但这听起来有点矫枉过正。只是以为我会扔掉它。