C# __DynamicallyInvokable 属性有什么用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12550749/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 23:38:26  来源:igfitidea点击:

What is the __DynamicallyInvokable attribute for?

c#dynamic-invoke

提问by Jamie Dixon

Looking through System.Linq.Enumerablein DotPeek I notice that some methods are flavoured with a [__DynamicallyInvokable]attribute.

综观System.Linq.Enumerable在DotPeek我注意到,有些方法是调味用[__DynamicallyInvokable]的属性。

What role does this attribute play? Is it something added by DotPeek or does it play another role, perhaps informing the compiler on how best to optimise the methods?

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

采纳答案by Hans Passant

It is undocumented, but it looks like one of the optimizations in .NET 4.5. It appears to be used to prime the reflection type info cache, making subsequent reflection code on common framework types run faster. There's a comment about it in the Reference Source for System.Reflection.Assembly.cs, RuntimeAssembly.Flags property:

它没有记录,但它看起来像是 .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;
 }

Without further hints what a "blessed API" might mean. Although it is clear from the context that this will only work on types in the framework itself. There ought to be additional code somewhere that checks the attribute applied to types and methods. No idea where that is located, but given that it would have to need to have a view of all .NET types to have a shot at caching, I can only think of Ngen.exe.

没有进一步提示“祝福的 API”可能意味着什么。尽管从上下文中可以清楚地看出这仅适用于框架本身的类型。在某处应该有额外的代码来检查应用于类型和方法的属性。不知道它的位置,但考虑到它必须有所有 .NET 类型的视图才能进行缓存,我只能想到 Ngen.exe。

回答by Stefan Dragnev

I found that it's used in the Runtime*Info.IsNonW8PFrameworkAPI()suite of internal methods. Having this attribute placed on a member makes IsNonW8PFrameworkAPI() return falsefor it and thus makes the member available in WinRT applications and shuts up the The API '...' cannot be used on the current platform.exception.

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

Profiler writers should place this attribute on members emitted by their profiler into framework assemblies, if they want to access them under WinRT.

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