关于C#:什么是 __DynamicallyInvokable属性?

What is the __DynamicallyInvokable attribute for?

通过dotpeek中的System.Linq.Enumerable,我注意到有些方法带有[__DynamicallyInvokable]属性。

这个属性扮演什么角色?它是由dotpeek添加的,还是扮演另一个角色,可能会通知编译器如何最好地优化这些方法?


它是未记录的,但看起来像.NET 4.5中的一个优化。它似乎用于启动反射类型信息缓存,从而使常见框架类型上的后续反射代码运行得更快。在system.reflection.assembly.cs、runtimeassembly.flags属性的引用源中有关于它的注释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 // 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下访问由其探查器发出的成员,则应将该属性放在框架程序集中。