提出一种通用方法在FAIL上抛出特定的异常类型

时间:2008-09-03 10:08:12

标签: c# generics exception

是的,我知道我完全会看到这个人的白痴,但我的大脑只是而不是今天早上开始装备。

我想要一个方法,我可以说“如果它变坏了,请回到这种类型的异常”,对吗?

例如,像(这不起作用):

    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


更新

感谢回复的人,看起来我不是一个完整的白痴! ;)

好的,所以VegardSam使我能够实例化正确的类型,但显然因为消息参数被读取而卡住了 - 仅在实例化之后。

Matt用他的回答击中了头部的钉子,我已经测试了这一切并且一切正常。以下是示例代码:

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

甜! :)

谢谢你们!

5 个答案:

答案 0 :(得分:16)

你几乎可以这样做:

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

但是,由于Exception.Message是只读的,因此无法编译。它只能通过将它传递给构造函数来赋值,并且没有办法用非默认构造函数来约束泛型类型。

我认为你必须使用反射(Activator.CreateInstance)来使用message参数“new up”自定义异常类型,如下所示:

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

编辑哎呀刚刚意识到你想要返回异常,而不是抛出异常。同样的原则也适用,所以我将把答案保留为throw语句。

答案 1 :(得分:9)

解决方案的唯一问题是可以创建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();
    }
}

答案 2 :(得分:1)

我一直在实例化内联我要抛出的异常类型,如下所示:

if (ItemNameIsValid(ItemName, out errorMessage))
    throw new KeyNotFoundException("Invalid name '" + ItemName + "': " + errorMessage);
if (null == MyArgument)
    throw new ArgumentNullException("MyArgument is null");

答案 3 :(得分:0)

您是否尝试过:

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

因为我觉得不需要输入泛型约束,因为所有可抛出的异常必须继承System.Exception。

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

答案 4 :(得分:-1)

我认为因为所有异常都应该有一个无参数构造函数,并且具有Message属性,所以以下内容应该有效:

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

编辑:好的,消息是只读的,所以你必须希望该类实现异常(字符串)构造函数。

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