代码之家  ›  专栏  ›  技术社区  ›  Rob Cooper

请求泛型方法在失败时引发特定的异常类型

  •  11
  • Rob Cooper  · 技术社区  · 18 年前

    对,我知道我会用这个看起来像个白痴,但我的大脑只是 不 今天早上开始准备。

    我想有一个方法,在这里我可以说“如果它坏了,就用这种类型的异常返回”,对吗?

    例如,( 这不管用 ):

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

    现在让我困惑的是我们 知道 由于 哪里 条款。但是,代码失败,因为我们不能隐式强制转换 例外 到 ExpType . 我们也不能显式地转换它,例如:

        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;
        }
    

    甜美!:)

    谢谢大家!

    5 回复  |  直到 14 年前
        1
  •  15
  •   Matt Hamilton    18 年前

    你几乎可以这样做:

    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语句一样留下我的答案。

        2
  •  9
  •   samjudson    18 年前

    解决方案的唯一问题是,可以创建一个异常的子类,该类不使用单个字符串参数实现构造函数,因此可能会引发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();
        }
    }
    
        3
  •  1
  •   MiloNC    14 年前

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

    if (ItemNameIsValid(ItemName, out errorMessage))
        throw new KeyNotFoundException("Invalid name '" + ItemName + "': " + errorMessage);
    if (null == MyArgument)
        throw new ArgumentNullException("MyArgument is null");
    
        4
  •  0
  •   Jon Limjap    18 年前

    您是否尝试过:

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

    因为我有一种感觉,把泛型约束作为所有可抛弃的异常都不必要。 必须 仍从System.Exception继承。

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

        5
  •  -1
  •   samjudson    18 年前

    我认为所有的异常都应该有一个无参数的构造函数,并且 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);
    }