有人能解释一下,当选项只因派生的参数类型而异时,如何选择重载方法吗?例如,以下代码:
using System;
public class Program
{
public static void LogException(AggregateException aggrException, string message)
{
Console.WriteLine(string.Format("{0} Inner exceptions on following logs.n (Type: {1}); (Message: {2})", message, aggrException.GetType(), aggrException.Message, aggrException.StackTrace));
foreach (var ie in aggrException.InnerExceptions)
LogException(ie, "Inner Exception.");
}
public static void LogException(Exception exception, string message)
{
Console.WriteLine(string.Format("{0}n (Type: {1}); (Message: {2})", message, exception.GetType(), exception.Message, exception.StackTrace));
if (exception.InnerException != null)
LogException(exception.InnerException, "Inner Exception.");
}
public static void Main()
{
var invadidOpExcep1 = new InvalidOperationException("%INVALID_OP1%");
LogException(invadidOpExcep1, "LOG1");
Console.WriteLine("------------------------------------------------");
var argumentExcep1 = new ArgumentException("%ARGUMENT1%");
LogException(argumentExcep1, "LOG2");
Console.WriteLine("------------------------------------------------");
var aggregateExcep1 = new AggregateException("%AGGREGATE1%", invadidOpExcep1, argumentExcep1);
LogException(aggregateExcep1, "LOG3");
Console.WriteLine("------------------------------------------------");
var indORExcep1 = new IndexOutOfRangeException("%INDOR1%");
var aggregateExcep2 = new AggregateException("%AGGREGATE2%", aggregateExcep1, indORExcep1);
LogException(aggregateExcep2, "LOG4");
}
}
产生以下输出:
LOG1
(Type: System.InvalidOperationException); (Message: %INVALID_OP1%)
------------------------------------------------
LOG2
(Type: System.ArgumentException); (Message: %ARGUMENT1%)
------------------------------------------------
LOG3 Inner exceptions on following logs.
(Type: System.AggregateException); (Message: %AGGREGATE1%)
Inner Exception.
(Type: System.InvalidOperationException); (Message: %INVALID_OP1%)
Inner Exception.
(Type: System.ArgumentException); (Message: %ARGUMENT1%)
------------------------------------------------
LOG4 Inner exceptions on following logs.
(Type: System.AggregateException); (Message: %AGGREGATE2%)
Inner Exception.
(Type: System.AggregateException); (Message: %AGGREGATE1%)
Inner Exception.
(Type: System.InvalidOperationException); (Message: %INVALID_OP1%)
Inner Exception.
(Type: System.IndexOutOfRangeException); (Message: %INDOR1%)
日志1到3可以。在前两个中,InvalidOperationException
和ArgumentException
都是Exception
s,而不是AggregateException
s,因此调用取Exception
的LogException
。在第三个例子中,传递了一个AggregateException
,因此调用了将该类型作为参数的重载。但在日志4上,通过一个"内部"有另一个AggregateException
的AggregateException
,我预计它会调用两次AggregateException
过载,这意味着,我预计第四个日志是:
LOG4 Inner exceptions on following logs.
(Type: System.AggregateException); (Message: %AGGREGATE2%)
Inner Exception. Inner exceptions on following logs.
(Type: System.AggregateException); (Message: %AGGREGATE1%)
Inner Exception.
(Type: System.InvalidOperationException); (Message: %INVALID_OP1%)
Inner Exception.
(Type: System.ArgumentException); (Message: %ARGUMENT1%)
Inner Exception.
(Type: System.IndexOutOfRangeException); (Message: %INDOR1%)
有人能告诉我们这里发生了什么吗?
提前谢谢。
AggregateException.InnerExceptions
属于System.Collections.ObjectModel.ReadOnlyCollection<Exception>
类型。这意味着您的foreach变量ie
的类型为Exception
。因为LogException
的调用是静态调度的(在编译时(,所以编译器选择具有Exception
签名的重载。
方法调用在编译时解析。在Log4中,您传递一个AggregateException
,正如您所期望的,LogException(AggregateException, string)
被调用。
然后,根据调用InnerException
的结果调用LogException
。InnerException
返回一个Exception
,因此调用LogException(Exception, string)
。实际返回的运行时类型无关紧要,因为解析是在编译时完成的。