Интерпретация коллекции MethodBody.ExceptionHandlingClauses

Я использую отражение для анализа блоков обработки исключений метода с [ExceptionHandlingClauses] собственность [MethodBody] учебный класс. Я не мог понять из Документации MSDN, как ведет себя эта коллекция и как ее интерпретировать. Допустим, вы хотите утверждать, что:

  • метод содержит ровно один блок try.
  • этот единственный блок содержит ровно один catch пункт.
  • этот единственный блок содержит finally пункт.

Пожалуйста, постарайтесь не выводить контекст из следующего кода, поскольку он слишком сложен для объяснения здесь. Это просто иллюстративный код и может быть плохого дизайна. Рассмотрим следующую иерархию:

// 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] НЕ содержат блоки обработки исключений.
  • [OnTest] Метод всех классов Tier 3 содержит ровно один блок обработки исключений, а в некоторых случаях вложенный блок и / или несколько [using] заявления.

Я получаю все классы уровня 3 из этой сборки, перебираю каждый тип, получаю [MethodInfo] объекты для каждого метода, получить [MethodBody] возразить и осмотреть его [ExceptionHandlingClauses] коллекция. Результат довольно странный для [OnTest] метод. [ExceptionHandlingClauses] Коллекция показывает от 0 до 6 предложений, каждое из которых имеет [Flag] значение любого [Catch] или же [Finally], Кажется, что нет абсолютно никакой корреляции между ожидаемым количеством [catch/finally] блоки и что показывает эта коллекция.

Иногда это даже показывает два [Finally] пункты в методах, которые даже не имеют [try/catch] блок.

Сначала я подумал, что это может быть связано с наследованием, но ни один из базовых классов не имеет реализаций, не говоря уже о блоках обработки исключений.

Некоторое руководство будет оценено.

1 ответ

Решение

ExceptionHandlingClauses свойство предоставляет информацию об условиях обработки исключений в скомпилированном байт-коде. Семантика блоков обработки исключений в байт-коде регулируется стандартом ECMA-335, а не ECMA-334 (стандарт языка C#). Правила для блоков обработки исключений в C# отличаются от правил, налагаемых байт-кодом, поэтому компилятор иногда компилирует код таким образом, что получается то, что кажется странным блоками обработки исключений, но фактически приводит к правильной семантике времени выполнения в соответствии с исходным кодом C#,

В других случаях C# предоставляет "синтаксический сахар" для функций, не поддерживаемых примитивами байт-кода. Например, using а также lock операторы в C# оба реализуются путем компиляции до try/finally блоки, которые будут включены в ExceptionHandlingClauses имущество.

Другие вопросы по тегам