Поделиться через


Класс System.Reflection.Emit.DynamicMethod

Замечание

В этой статье приводятся дополнительные замечания к справочной документации по этому API.

Класс можно использовать DynamicMethod для создания и выполнения метода во время выполнения, не создавая динамическую сборку и динамический тип для хранения метода. Исполняемый код, созданный JIT-компилятором, освобождается, когда объект DynamicMethod восстанавливается. Динамические методы являются наиболее эффективным способом создания и выполнения небольших объемов кода.

Динамический метод может быть размещен анонимно или логически связан с модулем или типом.

  • Если динамический метод размещен анонимно, он находится в предоставленной системой сборке и поэтому изолирован от другого кода. По умолчанию у него нет доступа к недоступным данным. Анонимный динамический метод может иметь ограниченную возможность обхода проверок видимости компилятора JIT, если ему был предоставлен ReflectionPermission вместе с флагом ReflectionPermissionFlag.RestrictedMemberAccess. Уровень доверия сборки, чьи непубличные члены доступны динамическим методом, должен быть равен или являться подмножеством уровня доверия стека вызовов, который испустил динамический метод. Для получения дополнительных сведений об анонимно размещаемых динамических методах см. Пошаговое руководство: создание кода в сценариях частичного доверия.

  • Если динамический метод связан с указанным модулем, динамический метод фактически глобальный для этого модуля. Он может получить доступ ко всем типам в модуле и всем internal (Friend в Visual Basic) членам типов. Можно связать динамический метод с любым модулем, независимо от того, был ли создан модуль вами, при условии, что требование для ReflectionPermission с флагом RestrictedMemberAccess может быть удовлетворено стеком вызовов, в котором присутствует ваш код. ReflectionPermissionFlag.MemberAccess Если этот флаг включен в грант, динамический метод может обойти проверки видимости компилятора JIT и получить доступ к закрытым данным всех типов, объявленных как в модуле, так и в любом другом модуле в любой сборке.

    Замечание

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

  • Если динамический метод связан с указанным типом, он имеет доступ ко всем элементам типа независимо от уровня доступа. Кроме того, проверки видимости JIT можно пропустить. Это дает динамический метод доступа к частным данным других типов, объявленных в том же модуле или в любом другом модуле в любой сборке. Динамический метод можно связать с любым типом, но для выполнения кода необходимы флаги ReflectionPermission, RestrictedMemberAccess, и MemberAccess.

В следующей таблице показано, какие типы и члены доступны для анонимно размещенного динамического метода — с проверкой видимости JIT или без нее, в зависимости от того, предоставлен ли ReflectionPermission с флагом RestrictedMemberAccess.

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

В следующей таблице показано, какие типы и члены доступны динамическому методу, связанному с модулем или типом в модуле.

Пропустить проверки видимости JIT Связанный с модулем Связанный с типом
нет Публичные и внутренние члены публичных, внутренних и частных типов в модуле.

Публичные элементы общедоступных типов в любой библиотеке.
Все члены связанного типа. Общедоступные и внутренние члены всех остальных типов внутри модуля.

Публичные элементы общедоступных типов в любой библиотеке.
Да Все члены всех типов в любой ассемблее. Все члены всех типов в любой ассемблее.

Динамический метод, связанный с модулем, имеет разрешения этого модуля. Динамический метод, связанный с типом, имеет разрешения модуля, содержащего этот тип.

Динамические методы и их параметры не должны быть именованы, но можно указать имена, помогающие в отладке. Пользовательские атрибуты не поддерживаются в динамических методах или их параметрах.

Хотя динамические методы являются static методами (Shared методами в Visual Basic), расслабленные правила для привязки делегата позволяют динамическому методу быть привязанным к объекту, чтобы он действовал как метод экземпляра при вызове с помощью этого экземпляра делегата. Пример, который демонстрирует это, предоставляется для перегрузки метода CreateDelegate(Type, Object).

Проверка

В следующем списке приведены условия, при которых динамические методы могут содержать непроверяемый код. (Например, динамический метод не проверяется, если его InitLocals свойство имеет значение false.)

  • Динамический метод, связанный с критической для безопасности сборкой, также является критически важным для безопасности и может пропустить проверку подлинности. Например, сборка без атрибутов безопасности, выполняемая в качестве классического приложения, рассматривается как критически важное для среды выполнения. При связывании динамического метода с сборкой динамический метод может содержать неподверяемый код.
  • Если динамический метод, содержащий непроверяемый код, связан с сборкой с прозрачностью уровня 1, компилятор JIT вставляет запрос безопасности. Запрос завершается успешно, только если динамический метод выполняется полностью доверенным кодом. См. Security-Transparent код, уровень 1.
  • Если динамический метод, содержащий неподдерживаемый код, связан с сборкой с уровнем прозрачности 2 (например, mscorlib.dll), он создает исключение (внедренное компилятором JIT) вместо того, чтобы требовать безопасность. См. Security-Transparent код, уровень 2.
  • Анонимно размещённый динамический метод, содержащий непроверяемый код, всегда вызывает исключение. Он никогда не может пропускать проверку, даже если она создана и выполняется полностью доверенным кодом.

Исключение, которое возникает для непроверяемого кода, зависит от способа вызова динамического метода. При вызове динамического метода с помощью делегата, возвращаемого из CreateDelegate метода, VerificationException выбрасывается исключение. При вызове динамического метода с помощью метода Invoke выбрасывается TargetInvocationException, содержащий внутренний VerificationException.