NET面试题:可否定义拥有返回值的方法的委托链
在前文中,笔者已经介绍了链式委托的基本原理。本节将针对委托返回值的问题进行讨论。
  所涉及的知识点
· 链式委托的返回值
  分析问题
委托的方法既可以是无返回的方法,也可以是有返回值的方法。回顾一下委托的使用:
public delegate int Meth();
Meth a = new Meth ( /* 添加方法 */ );
a += /* 方法 */;
a += /* 方法 */;
int returnval = a();
当使用类似的代码时,委托链表中各个方法的返回值起了冲突,最后一行代码只从委托中取得一个返回值,而事实上该委托链包含三个方法,而每个方法都具有一个返回值。读者将会看到,当这样使用委托时,只有委托链上最后被调用的方法返回值才被返回。代码6-3展示了这一特性。
代码6-3  链式委托:MMulticastDelegate.cs
namespace NET.MST.Sixth.DelegateReturn
{
    //定义一个委托
    public delegate String GetStringDelegate();
    class DelegateReturn
    {
        static void Main(string[] args)
        {
            //GetSelfDefinedString被最后添加
            GetStringDelegate _myDelegate1 = new GetStringDelegate(GetTimeString);
            _myDelegate1 += GetTypeName;
            _myDelegate1 += GetSelfDefinedString;
            Console.WriteLine(_myDelegate1());
            //GetTimeString被最后添加
            GetStringDelegate _myDelegate2 = new GetStringDelegate(GetSelfDefined String);
            _myDelegate2 += GetTypeName;
            _myDelegate2 += GetTimeString;
            Console.WriteLine(_myDelegate2());
            //GetTypeName被最后添加
            GetStringDelegate _myDelegate3 = new GetStringDelegate(GetSelfDefined String);
            _myDelegate3 += GetTimeString;
            _myDelegate3 += GetTypeName;
            Console.WriteLine(_myDelegate3());
            Console.Read();
        }
        static String GetTimeString()
        {
            return DateTime.Now.ToString();
        }
        static String GetTypeName()
        {
            return typeof(DelegateReturn).ToString();
        }
        static String GetSelfDefinedString()
        {
            return "我是字符串。";
        }
    }
}
下面是这段程序的执行结果:
我是字符串。
2008-2-1 10:43:33
NET.MST.Sixth.DelegateReturn.DelegateReturn
正如读者所看到的,虽然委托链中所有的方法都被正确执行,但委托的使用者只得到了最后一个方法所返回的值。这个结果非常糟糕,丢失大部分的方法返回值可能会造成很大的麻烦。在一些程序中,往往不采用异常机制,而是返回一个非0的整数来告诉使用者方法执行不成功。如果该方法被添加到一个委托链的中间,那这个返回值很可能就被丢失了,在这种情况下,程序员需要手动地执行委托链中的每个方法。下面笔者重写了代码6-3中的main方法。
static void Main(string[] args)
{
    GetStringDelegate _myDelegate1 = new GetStringDelegate(GetTimeString);
    _myDelegate1 += GetTypeName;
    _myDelegate1 += GetSelfDefinedString;
    foreach (Delegate d in _myDelegate1.GetInvocationList())
        Console.WriteLine(d.DynamicInvoke());
    Console.Read();
}
在这种情况下,委托链中每个方法的返回值都不会丢失,下面是程序的执行结果:
2008-2-1 11:06:32
NET.MST.Sixth.DelegateReturn.DelegateReturn
我是字符串。
  答案
委托可以是带有返回值的方法,但多于一个带返回值的方法被添加到委托链中时,程序员需要手动地调用委托链上的每个方法,否则委托使用者将只能得到委托链上最后一个被执行方法的返回值
 

更多.net面试题,.net电子书,.net教学视频请参考"爱学网izixue"