在DotPeek中查看System.Linq.Enumerable
我注意到某些方法使用[__DynamicallyInvokable]
属性进行了调整。
此属性扮演什么角色?它是由DotPeek添加的还是它扮演另一个角色,可能告诉编译器如何最好地优化方法?
答案 0 :(得分:128)
它没有文档,但它看起来像.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。
答案 1 :(得分:22)
我发现它在Runtime*Info.IsNonW8PFrameworkAPI()
内部方法套件中使用。将此属性放在成员上会使IsNonW8PFrameworkAPI()为其返回false
,从而使该成员在WinRT应用程序中可用并关闭The API '...' cannot be used on the current platform.
异常。
如果想要在WinRT下访问它们,则Profiler编写者应将此属性放在其探查器发出的成员中,并将其置于框架程序集中。