【问题标题】:Throw exception of type 'E' with reflection in vb.net在 vb.net 中通过反射引发类型“E”的异常
【发布时间】:2013-12-10 03:39:55
【问题描述】:

我想实现一个具有以下逻辑的方法:

mymethod(exceptionT as Type)
throw new exception of type exceptionT

在 asp.net 4 (vb.net) 中,我这样写:

Public Shared Function raiseMyException(ByVal extype As Type) As Boolean
  Dim constructor = extype.GetConstructor(New Type() {Type.GetType("String")})
  Dim ex = constructor.Invoke(New String() {"Exception raised"})
 'Throw ex

但这失败了:throw 应该派生自 System.exception

如何通过反射抛出自定义类型的异常?

【问题讨论】:

  • 您的自定义类型必须从 Exception 继承,否则 throw 毫无头绪。对您在这里尝试实现的目标感到有些困惑
  • 所有异常都继承自Exception,那么您使用反射是否有特定原因?使用您的代码,可以使用作为参数传递的任何类型,因为您不限制实际需要的类型。
  • 很抱歉让您感到困惑。我正在为一些非常古老的图书馆做一个包装器。有很多方法实际上是相同的:调用原始方法,如果返回 1 则返回 true,或者如果给出错误描述则引发异常。因此,我想创建一个基本方法,该方法接受输入原始方法的名称、所需的参数和要引发的异常类型(如果是这样的话)。
  • 对不起。我现在真的很累。 Ric 的解决方案是可行的方法。

标签: asp.net vb.net exception reflection


【解决方案1】:

你总是可以试试这个,它使用泛型:

Public Sub ThrowException(Of T As Exception)(message As String)
    Throw DirectCast(Activator.CreateInstance(GetType(T), message), T)
End Sub

用法:

ThrowException(Of ArgumentException)("Error Message here")

您可以将ArgumentException 替换为源自Exception 的任何异常

但是正如@Steven Doggart 提到的,正常抛出异常不是更容易吗?

【讨论】:

  • 到那时,为什么还要使用Activator?你可以调用new T(message) 来实例化对象。
  • 那么new 必须具有指定的约束才能使用new。这样,DirectCast 会将返回类型从object 类型的CreateInstance(..) 更改为受限于ExceptionT,并调用异常的构造函数。认为这值得一提。另一个问题是,使用new 作为约束会强制使用默认的无参数构造函数(如果存在)。
  • 事实上,“New T("some text")”是无效的(我得到的错误是意大利语,类似于“无法使用带有参数的新的没有”新”约束)
  • 我知道,这就是我在评论中所说的。您将需要这个:raiseMyException(Of T As {Exception, New})()... 但在这样做时,您无法传递您选择的自定义消息,也无法设置一个。我的回答允许你这样做。
  • 啊,我明白了。当时我面前没有视觉工作室,所以我无法测试它。我只是假设如果你有Exception 约束,它可以让你创建一个新的约束而无需指定New 约束,因为毕竟Exception 是可实例化的。 +1
【解决方案2】:

我怀疑您的问题是类型推断功能不适合您。 VB.NET 会尽力为您推断类型,但如果类型不清楚,则根据上下文,它可能会导致类型错误。在这种情况下,由于您使用反射来创建对象,因此编译器无法在构建时正确确定类型。我怀疑您的ex 变量可能被键入为Object 而不是Exception。您可以通过指定类型来修复它,如下所示:

Public Shared Function raiseMyException(ByVal extype As Type) As Boolean
    Dim constructor = extype.GetConstructor(New Type() {Type.GetType("String")})
    Dim ex As Exception = DirectCast(constructor.Invoke(New String() {"Exception raised"}), Exception)
    Throw ex

顺便说一句,值得一提的是,如果它适用于你的情况,如果你把它做成一个泛型方法会更容易,像这样:

Public Shared Function raiseMyException(Of T As Exception)() As Boolean
    Throw New T("Exception Raised")

当然,到那时,直接抛出异常而不是调用那个方法并不容易,但那是另一个讨论......

【讨论】:

  • 感谢您对泛型方法的提示。无论如何,正如 Ric 指出的那样,我不能使用“New T(mystring)”。 Activator 解决了这个问题。
【解决方案3】:

试试这个:

Public Sub ThrowExceptionByType(exceptionType As Type)
    Dim ex As Exception = CType(exceptionType.Assembly.CreateInstance(exceptionType.FullName), Exception)
    Throw ex
End Sub

编辑: 如果类型不是异常,这显然会失败...... 我想你会得到一个 InvalidCastException 而不是你的自定义异常:) 也许您想检查一下...但是如果您确实想抛出 InvalidCastException 则会遇到问题...您可以检查您的个人类型是否确实继承了异常...但是如果不是... . 抛出你自己的 InvalidCastException?还是通过返回码处理?好吧,这取决于你。

【讨论】:

  • 感谢您的帮助。我会使用通用方法,因为我不想处理 InvalidCastException。
猜你喜欢
  • 2012-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-24
  • 2011-05-08
  • 2012-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多