繁体   English   中英

解释MethodBody.ExceptionHandlingClauses集合

[英]Interpreting MethodBody.ExceptionHandlingClauses collection

我使用反射来分析方法的异常处理块与[MethodBody]类的[ExceptionHandlingClauses]属性。 我无法从MSDN文档中弄清楚这个集合的行为以及如何解释它。 假设您想断言:

  • 一个方法只包含一个try块。
  • 单个块只包含一个catch子句。
  • 单个块包含finally子句。

请尽量不要从以下代码中导出上下文,因为它太复杂了,无法在此解释。 这只是说明性代码,可能设计不佳。 考虑以下heirarchy:

// Tier 1. Base class.
namespace ProductName
{
    // This is not an abstract class.
    // These tier 1 class methods to not have implementations or exception handling blocks.
    public class Template: System.IDisposable
    {
        public sealed void Launch () { this.OnLaunch(); }
        public sealed void Simulate () { this.OnSimulate(); }
        public sealed void Test () { this.OnTest(); }
        public sealed void Submit () { this.OnSubmit(); }
        public sealed void Exit () { this.OnExit(); }

        protected virtual void OnLaunch () { }
        protected virtual void OnSimulate () { }
        protected virtual bool OnTest () { return (false); }
        protected virtual void OnSubmit () { }
        protected virtual void OnExit () { }
    }
}

// Tier 2. Defines template platforms e.g. Access, Excel, etc.
// These tier 2 classes do not have implementations or exception handling blocks.
namespace ProductName.Access { public class Template: ProductName.Template { } }
namespace ProductName.Excel { public class Template: ProductName.Template { } }
namespace ProductName.Outlook { public class Template: ProductName.Template { } }
namespace ProductName.PowerPoint { public class Template: ProductName.Template { } }
namespace ProductName.Word { public class Template: ProductName.Template { } }

// Tier 3. Defines individual templates in each platform.
// Each platform will have hundreds of classes with a [Template_########] naming convention.
// Each class overrides all virtual methods with exactly one try/catch/finally block in OnTest and none in other methods.
namespace ProductName.Access.Templates { public class Template_00000001: ProductName.Access.Template { } }
namespace ProductName.Excel.Templates { public class Template_00000001: ProductName.Excel.Template { } }
namespace ProductName.Outlook.Templates { public class Template_00000001: ProductName.Outlook.Template { } }
namespace ProductName.PowerPoint.Templates { public class Template_00000001: ProductName.PowerPoint.Template { } }
namespace ProductName.Word.Templates { public class Template_00000001: ProductName.Word.Template { } }

我已经了解了以下关于这些类的知识:

  • 第1层基类没有实现,因此没有异常处理块。
  • 第2层派生类没有实现,因此没有异常处理块。
  • 第3层派生类具有所有虚方法的实现,其中除[OnTest]之外的所有方法都不包含异常处理块。
  • 所有Tier 3类的[OnTest]方法只包含一个异常处理块,在某些情况下还包含嵌套块和/或一些[using]语句。

我从这个程序[MethodBody]获取所有第3层类,遍历每个类型,获取每个方法的[MethodInfo]对象,获取[MethodBody]对象并检查其[ExceptionHandlingClauses]集合。 对于[OnTest]方法,结果非常奇怪。 [ExceptionHandlingClauses]集合显示0到6个子句之间的任何一个子句,每个子句的[Flag]值为[Catch][Finally] 预期的[catch/finally]块数量与此集合显示的内容之间似乎完全没有相关性。

有时,它甚至在方法中显示两个[Finally]子句,甚至没有[try/catch]块。

起初我认为这可能与继承有关,但没有基类具有实现,更不用说异常处理块了。

一些指导意见将不胜感激。

ExceptionHandlingClauses属性提供有关已编译字节码中的异常处理子句的信息。 字节码中异常处理块的语义由ECMA-335标准控制,而不是由ECMA-334(C#语言标准)控制。 C#中的异常处理块的规则与字节码强加的规则不同,因此编译器有时会以产生看似奇怪的异常处理块的方式编译代码,但实际上根据原始C#代码产生正确的运行时语义。

在其他情况下,C#为字节码原语不支持的功能提供“语法糖”。 例如,C#中的usinglock语句都是通过编译为try / finally块来实现的,这些块将包含在ExceptionHandlingClauses属性中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM