【发布时间】:2020-03-18 21:06:56
【问题描述】:
Can anyone explain how which overloaded method is chosen when options only differ by a parameter type being derived? 例如以下代码:
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 都是Exceptions 并且不是AggregateExceptions,因此调用了带有Exception 的LogException。在第三个中,传递了一个AggregateException,因此调用了将该类型作为参数的重载。
但是在日志 4 上,传递了一个 AggregateException 有另一个 AggregateException 'inside',我预计它会调用 AggregateException 重载两次,这意味着,我预计第 4 个日志是:
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%)
谁能解释一下这里发生了什么?
提前致谢。
【问题讨论】:
-
根据编译时类型调用方法。您似乎实际上想知道如何绕过该行为。见标记重复。或者,您可能会发现在
foreach循环中创建ie的类型dynamic也会产生您想要的效果。 -
'有趣'事实上,如果我在 .NET Core(至少 3.1)上运行它,我就不需要这个代码,因为
AggregateException.Message已经包含了它的所有InnerExceptions'消息。
标签: c# recursion overloading