What is the __DynamicallyInvokable attribute for?
通过dotpeek中的System.Linq.Enumerable,我注意到有些方法带有[__DynamicallyInvokable]属性。
这个属性扮演什么角色?它是由dotpeek添加的,还是扮演另一个角色,可能会通知编译器如何最好地优化这些方法?
- string.empty也有这个,btw。
- IReadOnlyCollection也一样。
- 和System.ServiceModel v3的BasicHttpBinding.TextEncoding(在v4中上升到一个新的基类,成为HttpBindingBase.TextEncoding)
- 它还用于系统枚举中的整数值,如dayofweek。
- 有一次我遇到这样的情况:在生成的程序集中内联具有此属性的方法(datetime.addyears、.net 4.5)
它是未记录的,但看起来像.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。
- 看起来存储值被用来检查WP8上是否有可用的API。
- +1请看我对OP的Q的评论——在一个案例中,clr似乎在做基于这一点的诡计,那就是在统一下处理方法的"轻微"移动(例如从一个级别下降到一个新的基类)。
- 这就是(排字前进)技巧,完全不同。
- @Hanspassant有趣-听起来我可能错了,所以…没有考虑检查原始程序集/类型。归根结底,在4.5节中,引用的属性(而不是类型)相对于3.5节中的属性移动(从技术上讲,System.ServiceModel 3.0)。我曾假设统一一个拉埃多克斯(La EDOCX1)(1)的参考文献正在发挥作用,但仍有很多关于我具体问题的循环,无论如何都要做-将在适当时候向我的评论报告和/或消除任何误导性的语气…
- @来自进一步研究的Hanspasant…除了转发类型,我看不到任何重新输入转发的操作,所以在这一点上,我希望和完全不同的一点有所不同。工作中的力很简单,当您有一个引用System.ServiceModel v3的clr2组件时,根据clr4自动升级到System.ServiceModel v4加载它。有趣的一点是.NET 4.5对System.ServiceModel的位进行了就地更新,将新的基类放在下面,并将属性下移一个级别。
- 我的论点是,属性的存在在使这个重定向能够[相对]透明地管理中起到了一定的作用。注意,属性同时由属性本身和单个属性getter和属性setter承载。nb GetMethods()只在新位置显示它,而不管我有逻辑的exe或dll的支持运行时是什么。
- 它可以在Nay程序集中定义,并通过名称进行查找>>此"u dynamicallyInvokableAttribute"是在其自己的程序集中定义的类型。pp.vk.me/c6365518/v636518918/cb1b/8kcuadksipe.jpg
- 以下是指向引用源的链接:referencesource.microsoft.com/mscorlib/system/reflection/…
我发现它在Runtime*Info.IsNonW8PFrameworkAPI()套内部方法中使用。将此属性放置在成员上会使isnonw8pframeworkapi()为其返回false,从而使该成员在WinRT应用程序中可用,并关闭The API '...' cannot be used on the current platform.异常。
如果探查器编写器希望在WinRT下访问由其探查器发出的成员,则应将该属性放在框架程序集中。
- 是的,@hans找到的代码设置了RuntimeAssembly.InvocableAttributeCtorToken查找的标志,您提到的IsNonW8PFrameworkAPI()方法调用了该标志。