我很好奇为什么在C#中允许以下逻辑
private static void Foo(Func<Exception, string> func)
{
try
{
// ...
}
catch (ArgumentException ex)
{
func(ex);
}
}
虽然这不是
private static void Foo<T>(Func<T, string> func) where T : Exception
{
try
{
// ...
}
catch (ArgumentException ex)
{
func(ex);
}
}
据我所知,由于Func<in TArg1, out TResult>
委托自.NET 4.0以来具有逆变参数,第一种情况不是问题,但为什么切换到约束泛型类型会改变编译器应用这种逆转的能力?
答案 0 :(得分:3)
您的第一个函数将编译,但由于Func
参数的逆转,您只能传递Func
参数,该参数是Exception
的超类型。
Func<object, string> f = o => o.ToString();
Foo(f);
在第二个示例中不是这种情况,这需要您传递Func
参数,该参数是Exception
的子类型,例如
Func<InvalidOperationException> f = o => ...
这不安全。