11

是的,我知道我完全会用这个看起来像个白痴,但今天早上我的大脑并没有开始运转。

我想有一种方法,我可以说“如果它变坏了,就带着这种类型的异常回来”,对吧?

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

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

现在让我感到困惑的是,由于where子句,我们知道泛型类型将是异常类型。但是,代码失败了,因为我们不能将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让我可以实例化正确的类型,但显然卡住了,因为消息参数在实例化后是只读的。

马特的反应一针见血,我已经对此进行了测试,一切正常。这是示例代码:

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

甜的!:)

多谢你们!

4

5 回答 5

22

你几乎可以这样做:

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

但是,这不会编译,因为 Exception.Message 是只读的。它只能通过将其传递给构造函数来分配,并且没有办法用默认构造函数以外的东西来约束泛型类型。

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

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

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

于 2008-09-03T10:15:34.863 回答
10

该解决方案的唯一问题是可以创建 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();
    }
}
于 2008-09-03T10:56:24.733 回答
1

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

if (ItemNameIsValid(ItemName, out errorMessage))
    throw new KeyNotFoundException("Invalid name '" + ItemName + "': " + errorMessage);
if (null == MyArgument)
    throw new ArgumentNullException("MyArgument is null");
于 2012-02-02T14:25:31.037 回答
0

您是否尝试过:

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

因为我觉得没有必要放入通用约束,因为所有可抛出的异常都必须从 System.Exception 继承。

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

于 2008-09-03T10:12:41.703 回答
-1

我认为看到所有异常都应该有一个无参数的构造函数,并且有这个Message属性,所以下面应该工作:

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

编辑:好的, Message 是只读的,所以你必须希望类实现 Exception(string) 构造函数。

static ExType TestException<ExType>(string message) where ExType:Exception
{
    return new ExType(message);
}
于 2008-09-03T10:13:11.297 回答