c# – 使用基类型调用的通用方法
我有这样的情况:
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方法传递任何Exception类型,一切正常.当我做这样的事情时,事情开始变得很奇怪: // 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. 有什么建议吗? 编辑: 解决方法
那是因为ExceptionContext.Ex的静态类型是Exception.泛型方法在编译时绑定,它不知道异常的动态运行时类型是不同的. 下一个最好的办法是使用显式强制转换在编译时指定运行时类型: var fooInstance = factory.Create((MyCustomException)context.Ex); 这显然假设运行时类型是MyCustomException.如果不是,您将获得无效的强制转换异常. 您还可以使用dynamic将方法解析推迟到运行时: dynamic fooInstance = factory.Create((dynamic)context.Ex); 这里的风险是任何使用fooInstance的东西都是动态的,因此你没有编译时的安全性,并且在运行时才会发现任何错误(拼写错误的名称,错误的参数类型). 编辑 删除了这部分答案,因为ExceptionContext不在OPs控件之下. 您也可以将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); 但目前尚不清楚这是否适合您的整体计划. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |