要求通用方法在FAIL上引发特定的异常类型

时间:2020-03-05 18:46:56  来源:igfitidea点击:

是的,我知道我完全会和这个白痴在一起,但今天早上我的大脑还没动弹。

我想拥有一种方法,我可以说"如果情况不好,请返回这种类型的异常",对吗?

例如,类似的东西(这不起作用):

static ExType TestException<ExType>(string message) where ExType:Exception
    {
        Exception ex1 = new Exception();
        ExType ex = new Exception(message);
        return ex;
    }

现在令我困惑的是,我们知道由于where子句,泛型类型将成为Exception类型。但是,代码失败,因为我们无法将Exception隐式转换为ExType。我们也不能显式转换它,例如:

static ExType TestException<ExType>(string message) where ExType:Exception
    {
        Exception ex1 = new Exception();
        ExType ex = (ExType)(new Exception(message));
        return ex;
    }

那样也失败了。那么这种事情可能吗?我有一种很强烈的感觉,那就是它真的很简单,但是我对旧的头皮却很不满意,所以要给我一些放松:P

更新

谢谢你们的回应,看来我不是个白痴! ;)

好的,所以Vegard和Sam使我进入了可以实例化正确类型的地步,但随后显然卡住了,因为消息参数在实例化之后是只读的。

Matt的回应打在了头上,我已经测试过了,一切都很好。这是示例代码:

static ExType TestException<ExType>(string message) where ExType:Exception, new ()
    {
        ExType ex = (ExType)Activator.CreateInstance(typeof(ExType), message);
        return ex;
    }

甜的! :)

谢谢你们!

解决方案

回答

我们是否尝试过:

static T TestException<Exception>(string message)
{}

因为我感觉到没有必要放入泛型约束,因为所有可抛出的异常都必须继承自System.Exception。

请记住,泛型确实接受继承的类型。

回答

我认为所有异常都应该具有无参数的构造函数,并具有Message属性,因此以下内容应该起作用:

static ExType TestException<ExType>(string message) where ExType:Exception
{
    ExType ex = new ExType();
    ex.Message = message;
    return ex;
}

编辑:好的,消息是只读的,因此我们必须希望该类改为实现Exception(string)构造函数。

static ExType TestException<ExType>(string message) where ExType:Exception
{
    return new ExType(message);
}

回答

我们几乎可以这样做:

static void TestException<E>(string message) where E : Exception, new()
{
    var e = new E();
    e.Message = message;
    throw e;
}

但是,由于Exception.Message是只读的,因此无法编译。只能通过将其传递给构造函数来进行分配,并且除了默认构造函数之外,没有其他方法可以约束泛型类型。

我认为我们必须使用反射(Activator.CreateInstance)来"新建"带有message参数的自定义异常类型,如下所示:

static void TestException<E>(string message) where E : Exception
{
    throw Activator.CreateInstance(typeof(E), message) as E;
}

Edit Oops刚意识到我们要返回异常,而不是抛出异常。同样的原则适用,因此我将使用throw语句保持原样。

回答

解决方案的唯一问题是可以创建Exception的子类,该子类不使用单个字符串参数实现构造函数,因此可能引发MethodMissingException。

static void TestException<E>(string message) where E : Exception, new()
{
    try 
    {
      return Activator.CreateInstance(typeof(E), message) as E;
    } 
    catch(MissingMethodException ex) 
    {
      return new E();
    }
}