委托的方法既可以是无返回值的,也可以是有返回值的,但如果多一个带返回值的方法被添加到委托链中时,我们需要手动地调用委托链上的每个方法,否则只能得到委托链上最后被调用的方法的返回值。.
为了验证结论,我们可以通过如下代码进行演示:
// 定义一个委托
public delegate string GetStringDelegate();
class Program
{
static void Main(string[] args)
{
// GetSelfDefinedString方法被最后添加
GetStringDelegate myDelegate1 = GetDateTimeString;
myDelegate1 += GetTypeNameString;
myDelegate1 += GetSelfDefinedString;
Console.WriteLine(myDelegate1());
Console.WriteLine();
// GetDateTimeString方法被最后添加
GetStringDelegate myDelegate2 = GetSelfDefinedString;
myDelegate2 += GetTypeNameString;
myDelegate2 += GetDateTimeString;
Console.WriteLine(myDelegate2());
Console.WriteLine();
// GetTypeNameString方法被最后添加
GetStringDelegate myDelegate3 = GetSelfDefinedString;
myDelegate3 += GetDateTimeString;
myDelegate3 += GetTypeNameString;
Console.WriteLine(myDelegate3());
Console.ReadKey();
}
static string GetDateTimeString()
{
return DateTime.Now.ToString();
}
static string GetTypeNameString()
{
return typeof(Program).ToString();
}
static string GetSelfDefinedString()
{
string result = "我是一个字符串!";
return result;
}
}
其运行结果如下图所示:
从上图可以看到,虽然委托链中的所有方法都被正确执行,但是我们只得到了最后一个方法的返回值。在这种情况下,我们应该如何得到所有方法的返回值呢?回顾刚刚提到的GetInvocationList()方法,我们可以利用它来手动地执行委托链中的每个方法。
GetStringDelegate myDelegate1 = GetDateTimeString;
myDelegate1 += GetTypeNameString;
myDelegate1 += GetSelfDefinedString;
foreach (var del in myDelegate1.GetInvocationList())
{
Console.WriteLine(del.DynamicInvoke());
}
通过上述代码,委托链中每个方法的返回值都不会丢失,下图是执行结果: