__DynamicallyInvokable属性的用途是什么?

在查看DotPeek中的System.Linq.Enumerable时,我注意到一些方法带有[__DynamicallyInvokable]属性。

这个属性起什么作用?它是由DotPeek添加的,还是扮演了另一个角色,也许是通知编译器如何最好地优化方法?

28364 次浏览

它没有文档记录,但看起来像是.NET 4.5中的优化之一。它似乎用于启动反射类型信息缓存,使通用框架类型上的后续反射代码运行得更快。在System.Reflection.Assembly.CS的RuntimeAssembly.Flags属性的引用源中有一个关于它的注释:

 // 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.exe.

我发现它在Runtime*Info.IsNonW8PFrameworkAPI()内部方法套件中使用。将此属性放置在成员上会使isNonW8pFrameworkAPI()为其返回false,从而使该成员在WinRT应用程序中可用,并关闭The API '...' cannot be used on the current platform.异常。

如果探查器编写者想要在WinRT下访问由其探查器发出到框架程序集中的成员,则应将此属性放在这些成员上。

对不起,如果我回答晚了。此属性用于从托管代码调用非托管代码函数。它用于将托管语言与非托管语言分开。两个世界的屏障。它也用于安全原因。使非托管代码反射不可访问。