Для чего нужен атрибут DynamicallyInvokable?

глядя через System.Linq.Enumerable в DotPeek я замечаю, что некоторые методы приправлены

2 ответов


он недокументирован, но выглядит как одна из оптимизаций в .NET 4.5. Он, по-видимому, используется для Прайма кэша информации о типе отражения, что делает последующий код отражения на общих типах фреймворка быстрее. Есть комментарий об этом в справочном источнике для System.Отображение.Собрание.cs, RuntimeAssembly.Флаги свойство:

 // Each blessed API will be annotated with a "__DynamicallyInvokableAttribute".
 // This "__DynamicallyInvokableAttribute" is a type defined in its own assembly.
 // So the ctor is always a MethodDef and the type a TypeDef.
 // We cache this ctor MethodDef token for faster custom attribute lookup.
 // If this attribute type doesn't exist in the assembly, it means the assembly
 // doesn't contain any blessed APIs.
 Type invocableAttribute = GetType("__DynamicallyInvokableAttribute", false);
 if (invocableAttribute != null)
 {
     Contract.Assert(((MetadataToken)invocableAttribute.MetadataToken).IsTypeDef);

     ConstructorInfo ctor = invocableAttribute.GetConstructor(Type.EmptyTypes);
     Contract.Assert(ctor != null);

     int token = ctor.MetadataToken;
     Contract.Assert(((MetadataToken)token).IsMethodDef);

     flags |= (ASSEMBLY_FLAGS)token & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_TOKEN_MASK;
 }

без дальнейших намеков, что может означать" благословенный API". Хотя из контекста ясно, что это будет работать только на типах в сама структура. Где-то должен быть дополнительный код, который проверяет атрибут, применяемый к типам и методам. Не знаю, где это находится, но, учитывая, что для кэширования нужно иметь представление всех типов .NET, я могу думать только о Ngen.исполняемый.


я обнаружил, что он используется в Runtime*Info.IsNonW8PFrameworkAPI() набор внутренних методов. Если этот атрибут размещен на члене, IsNonW8PFrameworkAPI () возвращает false для него и, таким образом, делает член доступным в приложениях WinRT и закрывает The API '...' cannot be used on the current platform. исключения.

авторы профилировщиков должны поместить этот атрибут на члены, испускаемые их профилировщиком в сборки framework, если они хотят получить к ним доступ в WinRT.