这两个班级有什么区别?哪个更好?
class MulticastExample
{
delegate void ME();
ME me;
public MulticastExample()
{
ME a = new ME(() => Console.WriteLine("A"));
ME b = new ME(() => Console.WriteLine("B"));
me = a + b;
}
public void Run()
{
me();
}
}
-
class ListExample
{
delegate void LE();
List<LE> le = new List<LE>();
public ListExample()
{
LE a = new LE(() => Console.WriteLine("A"));
LE b = new LE(() => Console.WriteLine("B"));
le.Add(a);
le.Add(b);
}
public void Run()
{
foreach (var x in le)
{
x();
}
}
}
答案 0 :(得分:1)
我认为你应该使用第一个例子。请注意,您始终可以通过me.GetInvocationList()
获取“多播”代理中的项目列表。类型MulticastExample.ME
从System.Delegate
继承此方法。
当您分配到a
和b
时,您不必使用new
语法。相同的委托由以下人员创建:
ME a = () => Console.WriteLine("A");
请注意,ME
的每个实例都是不可变的,并且具有固定长度的调用列表。此列表保证至少包含一个项目。
当您“添加”或“减去”(合并或删除)委托时,原始实例将保持不变(不变性)并创建新实例。
如果“减法”的结果如:
ME c = b - a;
将提供零长度多播委托,不会创建新实例,而是返回null
引用(即c
变为null
)。因此,请在调用之前记住null
检查:c();
如果您选择使用List<T>
,则有一个区别(正如您现在可能知道的那样)List<>
是可变的。另请注意,您有责任检查List<>
中没有成员本身是多播的,因为.NET中的任何委托类型都允许多个项目的调用列表。
最后(但我想你知道),像ME
这样的委托类型不必嵌套在其他类型(在这种情况下是class
MulticastExample
)中,但是当你希望委托类型成为包含类的“实现细节”时,这很好。
如果您计划将委托类型设置为泛型类型,如果您打算与+
结合使用,请不要在其任何类型参数中使此类型为逆变(或此处不太有用的协变)。< / p>
答案 1 :(得分:1)
使用MulticastExample
,对me
的一次调用会将所有方法subscribed
调用到它。所以a
和b
将通过单个方式调用致电me
使用ListExample
,您必须单独调用每个代理人。因此,您必须单独调用 所做的a
和b
foreach
循环
如果a
和b
将引用相同签名的单个方法,则ListExample
是多余的。您应该使用MulticastExample
。