我读了那个
如果您正在使用多播代理,您应该知道 将调用链接到同一委托的方法的顺序是 正式未定义。因此,您应该避免编写代码 依赖于以任何特定顺序调用的此类方法。
但是当我尝试使用这段代码时
using System;
namespace Wrox.ProCSharp.Delegates
{
class Program
{
static void One()
{
Console.WriteLine("watch when i occur");
throw new Exception("Error in watching");
}
static void Two()
{
Console.WriteLine("count");
}
static void Three()
{
Console.WriteLine("great");
}
static void Main()
{
Action d1 = Two;
d1+=Two;
d1+=Two;
d1+=Two;
d1+=One;
d1+=Three;
d1+=Three;
d1+=Three;
Delegate[] delegates = d1.GetInvocationList();
foreach (Action d in delegates)
try
{
d1();
}
catch(Exception)
{
Console.WriteLine("Exception Caught");
}
}
}
}
这是我得到的输出
count
count
count
count
watch when i occur
Exception Caught
count
count
count
count
watch when i occur
Exception Caught
count
count
count
count
watch when i occur
Exception Caught
count
count
count
count
watch when i occur
Exception Caught
count
count
count
count
watch when i occur
Exception Caught
count
count
count
count
watch when i occur
Exception Caught
count
count
count
count
watch when i occur
Exception Caught
count
count
count
count
watch when i occur
Exception Caught
显然,委托是按照我编写的指定顺序执行的,并且Three()
方法都没有在引发异常的One()
方法之前执行。
所以我缺少一些东西,或者委托中的实际方法按指定的顺序执行,而我从书中读到的东西意味着别的东西。
答案 0 :(得分:6)
未定义 - 行为被指定为任意(就像你忘记了妻子的生日后发生的事情......)所以取决于任意行为是可能的危险。
可能是5年后,Microsoft发布了.NET 7并且您的程序结果发生了变化。那是"未定义"这意味着,今天没有多少测量值可以让您对下一个版本,甚至是您的计算机和Fred的计算机之间感到舒适。所以观察它只是有趣的,但对可靠性没有用。依靠你观察到的东西在技术上是错误的。
有时,供应商会专门记录未定义的内容,以便在实施过程中保持灵活性。
答案 1 :(得分:2)
"正式未定义"简单地说:无论发生什么,都是实施细节;它可能会像你自然期望的那样工作;它可能完全不同,要么完全有效。实现者没有需求mande它以任何特定顺序运行。此外,这可能会在框架版本,目标和实现之间发生变化。
基本上:即使它符合您的期望和愿望:不要依赖它继续这样做。
答案 2 :(得分:-1)
我不是高级程序员,但是在查看了您的代码之后,我可能会发现一些错误。
您需要使用此
Delegate[] delegates = d1.GetInvocationList();
foreach (Action d in delegates)
{
try
{
d();
}
catch(Exception e)
{
Console.WriteLine("Exception Caught : "+e.Message);
}
}
代替这个
Delegate[] delegates = d1.GetInvocationList();
foreach (Action d in delegates)
try
{
d1();
}
catch(Exception)
{
Console.WriteLine("Exception Caught");
}
这就是我得到的
count
count
count
count
watch when i occur
Exception Caught : Error in watching
great
great
great
很明显,调用列表中的委托是按顺序执行的
最诚挚的问候