加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使用基类型调用的通用方法

发布时间:2020-12-15 23:49:31 所属栏目:百科 来源:网络整理
导读:我有这样的情况: public class Foo{}public interface IBarin TEx where TEx : Exception{ Foo Build(TEx ex);}public class FooFactory{ public Foo CreateTEx(TEx ex) where TEx : Exception{ // blah }} 如果我调用FooFactory.Create方法传递任何Excepti
我有这样的情况:

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.

有什么建议吗?

编辑:
为了给出一点上下文,我试图在Microsoft.AspNetCore.Mvc.Filters.IExceptionFilter的自定义实现的OnException(ExceptionContext context)方法中运行异常特定的代码.

解决方法

When I call FooFactory.Create(),the passed exception is always of type System.Exception

那是因为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);

但目前尚不清楚这是否适合您的整体计划.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读