我想知道C#中的事件或多播委托是否包含一个内部列表来保存所有方法,有人知道吗?
答案 0 :(得分:10)
MulticastDelegate有一个委托链表,称为调用列表,由一个或多个元素组成。调用多播委托时,调用列表中的委托将按它们出现的顺序同步调用。如果在执行列表期间发生错误,则抛出异常。
更新1:
为了避免混淆:在.NET中,所有 Delegate
都继承自MulticastDelegate
,因此所有委托可以在其中保留多个元素调用列表。
更新2:
请参阅Jon Skeet的帖子,了解一个有趣的事实。 :)
答案 1 :(得分:3)
尽管MulticastDelegate
声明的文档存储了所有方法调用的链接列表,但我相信实际使用数组。示例代码:
using System;
using System.Collections;
using System.Reflection;
class Test
{
static void Main()
{
Action<string> a = x => Console.WriteLine("First " + x);
Action<string> b = y => Console.WriteLine("Second " + y);
Action<string> c = a + b;
foreach (var field in typeof(MulticastDelegate).GetFields
(BindingFlags.NonPublic | BindingFlags.Instance))
{
object value = field.GetValue(c);
Console.WriteLine("{0}: {1}", field.Name, value);
if (value != null && value.GetType().IsArray)
{
foreach (var subvalue in (IEnumerable)value)
{
Console.WriteLine(" - " + subvalue);
}
}
}
}
}
输出:
_invocationList: System.Object[]
- System.Action`1[System.String]
- System.Action`1[System.String]
_invocationCount: 2
_target: System.Action`1[System.String]
_methodBase:
_methodPtr: 2662852
_methodPtrAux: 1526207940
正如您所知,_invocationList
是一个包含两个单独操作的数组。 (我相信这些操作中的第一个将具有相同的_methodPtr,即多播委托知道第一个“本机”调用的方法,但使用其余的调用列表。)
答案 2 :(得分:0)
委托包含对方法的引用。它不包含方法本身。常规委托仅引用一种方法。
我强烈怀疑你在问别的东西,但没有完全阐明。也许你可以稍微扩展和澄清你的问题。