CLS比CLR更具限制性,它允许您抛出并捕获任何类型的对象(甚至是值类型)。为什么呢?
如果一些非符合CLS的代码在符合CLS的代码调用时抛出非异常派生对象会发生什么?
更新 第二个问题由@Marton回答。仍然想知道为什么。
答案 0 :(得分:5)
CLS指定了许多应用程序所需的最小语言功能集,如果API仅使用这些功能,则它可以被任何符合CLS的语言使用。所以自然它比CLR更具限制性。另一方面,CLR设计用于处理来自任何CLI兼容语言的manged代码。
允许抛出非CLS兼容异常(不是从 System.Exception 派生的异常)的语言示例是C ++ / CLI。这种语言被设计成普通C ++的超集,它包括抛出任何类型的异常的能力。这可能是抛出非CLS异常的唯一理由。
关于第二个问题。抛出非CLS异常时,在不同情况下会发生不同的事情:
在CLR 2.0及更高版本中,CLR内部始终将异常包装到 System.Runtime.CompilerServices.RuntimeWrappedException 中,该字段维护 Object 类型的字段引用原始异常。这允许记录堆栈跟踪。当它向上传播时:
如果 System.Runtime.CompilerServices.RuntimeCompatibilityAttribute 属性应用于CLR正在寻找匹配的catch块并且 WrapNonExceptionThrows 设置为true(由Visual C#和Basic编译器自动应用),然后异常继续被包装。
否则,如果未应用该属性或 WrapNonExceptionThrows 设置为false,则每次检查catch块进行匹配时都会解除该异常。
修改强>
在C#中,在上面的第一个项目符号和第二个项目符号的第二个案例中,捕获非CLS异常的唯一方法是使用无参数的catch块。
答案 1 :(得分:2)
为什么我不能回答,但第二部分我可以:
如果某些非符合CLS的代码抛出非异常会发生什么 由符合CLS的代码调用派生对象?
如果抛出一个非Exception派生的对象,它仍然会被符合CLS的代码捕获,因为它将被包装到RuntimeWrappedException
中。
(source article值得阅读以获取更多详细信息。)