【问题标题】:Why the CLS mandates the throwing/catching of Exception derived objects?为什么 CLS 要求抛出/捕获异常派生对象?
【发布时间】:2015-07-18 07:51:45
【问题描述】:

CLS 比 CLR 更具限制性,它允许您抛出和捕获任何类型的对象(甚至是值类型)。为什么?

如果某些不符合 CLS 的代码在被符合 CLS 的代码调用时抛出非异常派生对象,会发生什么情况?

更新 @Marton 回答的第二个问题。仍然想知道为什么。

【问题讨论】:

  • 应禁止不解释就投反对票
  • 存在 CLS 规则,因此用一种语言编写的代码抛出的异常可以被另一种语言编写的代码合理地捕获。 CLI 规范不排除它可能在某种晦涩的语言中有用以抛出其他东西的可能性。当然,您将很难找到这种语言的示例。发生的事情有点明显,程序崩溃了,无法捕获或诊断异常。
  • 原来不是那么明显,对吧?

标签: c# c++ .net clr cls


【解决方案1】:

为什么部分我无法回答,但第二部分我可以:

如果某些不符合 CLS 的代码抛出非异常会发生什么 由符合 CLS 的代码调用的派生对象?

如果你抛出一个非异常派生的对象,它仍然会被符合 CLS 的代码捕获,因为它会被包装到 RuntimeWrappedException 中。

source article 值得一读以了解更多详细信息。)

【讨论】:

    【解决方案2】:

    CLS 指定了许多应用程序所需的最小语言功能集,这样如果 API 仅使用这些功能,则任何符合 CLS 的语言都可以使用它。所以自然它比 CLR 更具限制性。另一方面,CLR 旨在处理来自任何 CLI 兼容语言的管理代码。

    允许抛出不符合 CLS 的异常(不是从 System.Exception 派生的异常)的语言示例是 C++/CLI。该语言被设计为普通 C++ 的超集,其中包括抛出任何类型异常的能力。这可能是引发非 CLS 异常的唯一充分理由。

    关于第二个问题。一个非 CLS 异常,当抛出时,在不同的情况下会发生不同的事情:

    • 如果 CLR 1.X 正在管理代码的执行,则异常会按原样传播。在仅支持 CLS 异常 (C#) 的语言中,异常只能由无参数的 catch 块捕获。没有简单的方法来访问异常,并且不会记录堆栈跟踪。
    • 在 CLR 2.0 及更高版本上,CLR 在内部始终将异常包装到 System.Runtime.CompilerServices.RuntimeWrappedException 中,该异常维护引用原始的 Object 类型的字段例外。这允许记录堆栈跟踪。当它向上传播时:

      1. 如果 System.Runtime.CompilerServices.RuntimeCompatibilityAttribute 属性应用于 CLR 在其中寻找匹配的 catch 块和 WrapNonExceptionThrows 的函数的程序集> 设置为 true(由 Visual C# 和 Basic 编译器自动应用),然后继续包装异常。

      2. 否则,如果未应用该属性或 WrapNonExceptionThrows 设置为 false,则每次检查 catch 块是否匹配时都会解开异常。

    编辑

    在 C# 中,在上面的第一个项目符号和第二个项目符号的第二种情况下,捕获非 CLS 异常的唯一方法是使用无参数的 catch 块。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-27
      • 1970-01-01
      • 2020-11-04
      • 1970-01-01
      • 2012-09-18
      • 2017-06-19
      相关资源
      最近更新 更多