__DynamicallyInvokable属性の目的は何ですか?


181

System.Linq.EnumerableDotPeek I通知にいくつかの方法がで味付けされていることを[__DynamicallyInvokable]属性。

この属性はどのような役割を果たしますか?それはDotPeekによって追加されたものですか、それとも別の役割を果たしていますか?


2
String.Emptyにもこれがあります。
Marc Gravell

1
そうIReadOnlyCollection<T>です。
Drew Noakes

1
そしてSystem.ServiceModel v3さんBasicHttpBinding.TextEncoding(V4に新しいベースクラスまで移動し、なっていたHttpBindingBase.TextEncoding
ルーベンBartelink

また、DayOfWeekなどのシステム列挙型の整数値にも使用されます
beauXjames

この属性を持つメソッドが生成されたアセンブリ(DateTime.AddYears、.Net 4.5)にインライン化された場合のケースがあります
gdbdable

回答:


139

文書化されていませんが、.NET 4.5の最適化の1つに似ています。これは、リフレクションタイプの情報キャッシュを準備するために使用されているようで、一般的なフレームワークタイプでの後続のリフレクションコードの実行が高速になります。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しか考えられません。


7
保存された値は、WP8でAPIが使用可能かどうかを確認するために使用されているようです。
usr

1
+1 OPのQに関する私のコメントを参照してください
。CLRが

2
それが[TypeForwardTo]トリックで、まったく別のものです。
ハンスパッサント

@HansPassant興味深い-間違っているように聞こえるので...元のアセンブリ/タイプを調べることは考えていませんでした。結論として、4.5では引用されたプロパティ(タイプではない)が3.5(技術的にはSystem.ServiceModel 3.0)であった場所に対して相対的に移動しました。私は、mscorlib参照の統合が機能していると想定していましたが、とにかくやるべき私の特定の問題について十分に振り返っています-やがて私のコメントに対する誤解を招く口調を報告および/または削除します...
Ruben Bartelink

1
@HansPassantさらなる調査から...転送タイプ以外のものを実行しているタイプ転送の何かを見ることができるので、この時点で、私は完全に異なる何かと異なることを頼みます。機能するのは、CLR2アセンブリを参照しているときに、CLR4 System.ServiceModel v3にロードしてそれをに自動アップグレードするだけSystem.ServiceModel v4です。おもしろいのは、.NET 4.5がSystem.ServiceModelその下にある新しい基本クラスをドロップするビットに対してインプレース更新を行い、プロパティを1レベルに移動することです
Ruben Bartelink 2013

23

Runtime*Info.IsNonW8PFrameworkAPI()内部メソッドのスイートで使用されていることがわかりました。この属性をメンバーに配置すると、IsNonW8PFrameworkAPI()がその属性を返すfalseため、WinRTアプリケーションでメンバーを使用できるようになり、The API '...' cannot be used on the current platform.例外がます。

プロファイラーの作成者は、WinRTでアクセスしたい場合、プロファイラーがフレームワークアセンブリに発行するメンバーにこの属性を配置する必要があります。


1
ええ、@ Hansが見つけたコードは、が探すフラグを設定します。RuntimeAssembly.InvocableAttributeCtorTokenこれは、IsNonW8PFrameworkAPI()あなたが言及するメソッドによって呼び出されます。
Mark Hurd
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.