在DotPeek中查看System.Linq.Enumerable
时,我注意到一些方法带有[__DynamicallyInvokable]
属性。
这个属性有什么作用?它是DotPeek添加的吗?还是它发挥了另一种作用,比如通知编译器如何最好地优化这些方法?
在DotPeek中查看System.Linq.Enumerable
时,我注意到一些方法带有[__DynamicallyInvokable]
属性。
这个属性有什么作用?它是DotPeek添加的吗?还是它发挥了另一种作用,比如通知编译器如何最好地优化这些方法?
这是一个未记录的优化功能,但看起来它是.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;
}
没有进一步的提示,"blessed API"可能意味着什么。尽管从上下文中清楚地表明这只适用于框架本身中的类型。应该有其他代码检查应用于类型和方法的属性。我不知道它位于何处,但考虑到它必须需要查看所有.NET类型才能尝试缓存,我只能想到Ngen.exe。
System.ServiceModel v3
时,在CLR4下加载它会自动升级为System.ServiceModel v4
。有趣的是,.NET 4.5对System.ServiceModel
的位进行了就地更新,并在下面移动了一个新的基类和属性。 - Ruben BartelinkGetMethods()
仅在新位置显示它,而不考虑exe或dll的supportedRuntime以及我的逻辑所在的位置。 - Ruben Bartelink我发现它被用于Runtime*Info.IsNonW8PFrameworkAPI()
一套内部方法中。 将此属性放置在成员上使得IsNonW8PFrameworkAPI()返回false
,使该成员在WinRT应用程序中可用,并消除了The API '...' cannot be used on the current platform.
异常。
如果Profiler编写者想要在WinRT下访问由其分析器发出到框架程序集中的成员,则应将此属性放置在这些成员上。
RuntimeAssembly.InvocableAttributeCtorToken
所寻找的标志,后者由你提到的 IsNonW8PFrameworkAPI()
方法调用。 - Mark Hurd抱歉回复晚了。此属性用于从托管代码调用非托管代码函数。它用于将托管语言与非托管语言分离,形成两个世界的屏障。它还用于安全原因,以使非托管代码反射不可访问。
IReadOnlyCollection<T>
也是如此。 - Drew NoakesSystem.ServiceModel v3
中的BasicHttpBinding.TextEncoding
(在V4中已经移动到一个新的基类,并成为HttpBindingBase.TextEncoding
)。 - Ruben Bartelink