【问题标题】:C++/C# exception throwingC++/C# 异常抛出
【发布时间】:2011-01-20 00:38:41
【问题描述】:

在 c++ 中,我可以将裸字符串作为异常抛出,但在 c# 中,我必须抛出 Exception。什么是 c# 相当于在 c++ 中抛出一个字符串?

例如,在 c++ 中我可以throw "something bad happened"。在 c# 中,这将是.....?

【问题讨论】:

  • 我可以尝试回答这个问题,但那只是抛出一个字符串。
  • 你的问题没有任何意义
  • 你的意思是在 C++ 中你可以做 throw "This is an error"; 并且你想要 C# 等价物。

标签: c# c++ exception-handling


【解决方案1】:

这个问题很模糊,但我认为问题是“在 C++ 中你可以抛出字符串;那么 C# 呢?”

在 C# 中,抛出异常的方式与在 C++ 中类似;主要区别在于,在 C# 中,您只能抛出派生自 System.Exception 的类,而在 C++ 中,您可以抛出任何类型(尽管通常建议仅抛出派生自 std::exception 或其他异常基类的类;我不会t 在 C++ 中抛出纯字符串)。

请记住,在 C# 中不仅有 System.Exception,还有大量描述引发异常的最常见原因的各种派生类(ArgumentOutOfRangeExceptionInvalidOperationExceptionOverflowException、. .. 只是说一些随机的),这为您提供了一种更好的方式来表达问题的类型(用类型表示,可以在catch 块中进行区分),并且您仍然可以指定通过在构造函数中传递您的自定义错误字符串。这比仅仅抛出一个字符串要好得多,还因为,如果异常“冒泡”到最上面的catch,或多或少可以记录问题并退出,仍然可以捕获通用System.Exception 和仍然显示/记录错误字符串。

请注意,这在 C++ 中也是可能的,但现成的派生异常(在 <stdexcept> 中)比 .NET Framework 提供的要少得多。

另一个重要的区别(来自 C++)是,在 C++ 中,来自 throw 的堆栈展开会立即销毁任何本地对象(构建 RAII 的概念),而在 C# 中,销毁是不确定的(它可能发生在在指向它们的变量超出范围之后的任何时刻);因此,重要的是让在这种情况下必须立即发布的类实现IDisposable 接口并使用using 块。

【讨论】:

  • 这就是为什么他们将 using 子句添加到 C# 以使销毁(或处置)具有确定性。
  • 从 c++ 转换为 c# 代码时,最方便的替代抛出原始类型的方法是什么?
  • 如果你添加一点关于如何抛出强类型异常并且从不抛出 System.Exception 的信息,你会得到我的 +1。
  • @Neil:我在您撰写评论时添加了它。 :)
  • @helicera:没有这样的替代品。在 C# 中,您只能抛出派生自 System.Exception 的类。您可以编写自己的异常类来包装原生类型,但在我看来,用 C# 惯用的抛出异常的方式替换所有原生类型抛出会更好(实际上,我会直接编写 C++ 原始代码使用std::exception & co.)
【解决方案2】:

C# 只允许抛出从 Exception 类派生的对象。 CLR 本身也允许抛出其他类型,所以如果你真的想要,你应该能够编写直接用其他语言或 IL 抛出字符串的方法。您将无法在 C# 中将其作为字符串异常捕获(仅作为具有“catch”且没有异常类型的未知异常)。

根据您的目标,throw new Exception("My string here"); 可能就足够了。 编辑(感谢 Neil):但您应该创建自己的异常,除非它是一次性实验。

【讨论】:

  • -1 不不不不看msdn.microsoft.com/en-us/library/ms173163.aspx 不要抛出 System.Exception。您抛出一个异常,以便调用代码可以发现失败 - 抛出一个通用异常将无法处理您的代码中可能发生的不同事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-01
  • 2015-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
  • 2013-08-17
相关资源
最近更新 更多