我有这样的情况:
public class Foo{}
public interface IBar<in TEx>
where TEx : Exception
{
Foo Build(TEx ex);
}
public class FooFactory{
public Foo Create<TEx>(TEx ex) where TEx : Exception{
// blah
}
}
如果我调用FooFactory.Create
方法传递任何异常类型,一切正常。当我做这样的事情时,事情开始变得很奇怪:
// this is an external class, cannot be changed.
public class ExceptionContext{
public Exception Ex{get; set;}
}
var context = new ExceptionContext(){ Ex = new MyCustomException (); }
var factory = new FooFactory();
var fooInstance = factory.Create(context.Ex);
当我致电FooFactory.Create()
时,传递的异常始终为System.Exception
类型,而不是我期望的MyCustomException
。
有什么建议吗?
编辑: 为了给出一点上下文,我试图在Microsoft.AspNetCore.Mvc.Filters.IExceptionFilter的自定义实现的OnException(ExceptionContext context)方法中运行异常特定的代码。
答案 0 :(得分:8)
当我致电
类型FooFactory.Create()
时,传递的异常始终为System.Exception
这是因为ExceptionContext.Ex
的静态类型是Exception
。泛型方法绑定在编译时,它不知道异常的动态运行时类型是不同的。
下一个最好的选择是使用显式强制转换在编译时指定运行时类型:
var fooInstance = factory.Create((MyCustomException)context.Ex);
显然假定运行时类型为MyCustomException
。如果不是,您将获得无效的强制转换异常。
您还可以使用dynamic
将方法解析推迟到运行时:
dynamic fooInstance = factory.Create((dynamic)context.Ex);
这里的风险是任何使用fooInstance
的东西都是动态的,所以你没有编译时的安全性,任何错误(拼写错误的名称,错误的参数类型)都不会被发现,直到运行时间。
修改强>
删除了这部分答案,因为ExceptionContext
不在OP控制之下。
<击>
你也可以使ExceptionContext
通用:
public class ExceptionContext<TEx>
where TEx : Exception
{
public <TEx> Ex{get; set;}
}
var context = new ExceptionContext<MyCustomException>(){ Ex = new MyCustomException (); }
var factory = new FooFactory();
var fooInstance = factory.Create(context.Ex);
如果要使用参数推断,请添加构造函数:
public class ExceptionContext<TEx>
where TEx : Exception
{
public ExceptionContext(TEx exception)
{
this.Ex = exception;
{
public <TEx> Ex{get; set;}
}
var context = new ExceptionContext(new MyCustomException());
var factory = new FooFactory();
var fooInstance = factory.Create(context.Ex);
但不清楚这是否适合您的整体计划。
击>
答案 1 :(得分:3)
考虑将ExceptionContext
类设为通用:
public class ExceptionContext<TEx> where TEx : Exception
{
public TEx Ex{get; set;}
}
通过这种方式,保留了派生类型最多的类型,而不是最基本类型(在您的情况下为System.Exception
)。
当然,当您的例外是System.Exception
的实例时,此规则的例外情况。