具有派生参数的递归重载方法
Recursive overload method with derived parameter
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
都是 Exception
而不是 AggregateException
,所以带 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%)
任何人都可以阐明这里发生的事情吗?
提前致谢。
AggregateException.InnerExceptions
是类型 System.Collections.ObjectModel.ReadOnlyCollection<Exception>
。这意味着您的 foreach 变量 ie
是 Exception
类型。因为 LogException
的调用是静态调度的(在编译时),所以编译器选择具有 Exception
签名的重载。
方法调用在编译时解决。在 Log 4 上,您传递了一个 AggregateException
,并且正如您所期望的那样,调用了 LogException(AggregateException, string)
。
然后,在 InnerException
的结果上调用 LogException
。 InnerException
returns一个Exception
,所以调用LogException(Exception, string)
。实际返回的运行时类型无关紧要,因为解析是在编译时完成的。
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
都是 Exception
而不是 AggregateException
,所以带 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%)
任何人都可以阐明这里发生的事情吗?
提前致谢。
AggregateException.InnerExceptions
是类型 System.Collections.ObjectModel.ReadOnlyCollection<Exception>
。这意味着您的 foreach 变量 ie
是 Exception
类型。因为 LogException
的调用是静态调度的(在编译时),所以编译器选择具有 Exception
签名的重载。
方法调用在编译时解决。在 Log 4 上,您传递了一个 AggregateException
,并且正如您所期望的那样,调用了 LogException(AggregateException, string)
。
然后,在 InnerException
的结果上调用 LogException
。 InnerException
returns一个Exception
,所以调用LogException(Exception, string)
。实际返回的运行时类型无关紧要,因为解析是在编译时完成的。