8

コンポーネントを呼び出すアセンブリに関するメタデータを取得する必要があります。そのため、使用Assembly.GetCallingAssembly()は自然にフィットするようです。ただし、Windows ストアを除くすべての場所で機能することがわかりました。サポートされている場所:

ただし、サポートされていないのは、Windows ストア アプリケーション内です。ポータブル クラス ライブラリを作成し、そこから Windows ストア アプリケーション内で呼び出すことはできますが、それを Windows ストア アプリ/クラス ライブラリに直接配置することはできません。

によって提供されるメタデータのタイプを取得するための回避策はありAssemblyますか?

4

2 に答える 2

7

Assembly.GetCallingAssemblyは WinRT で公開されていません。おそらく、そのセマンティクスがインライン化などに直面して信頼できないためです ( source )。ただし、Windows ストア アプリで許可されている制限されたリフレクションにはあまり適合しません。のようなものを取得できますAssembly.GetCurrentAssembly()。たとえば、次のようになります。

typeof(MainPage).GetTypeInfo().Assembly

しかし、それはまったく同じではありません。制限されたリフレクション モデルでは、.NET で可能なように実行時にスタック トレースを取得することもできません。

Assembly.GetCurrentAssembly()ポータブル クラス ライブラリに関しては、ポータブル クラス ライブラリでは一般的にサポートされていますが、WinRT ではサポートされていないということを言おうとしていました。しかし実際には、WinRT+.NET4.5 を除く WinRT を含むすべてのプロファイルに存在するようです。したがって、メソッドWinRT に存在します (さらに、リダイレクトのようなものは行われません) が、コンパイル時に利用可能なメタデータには表示されません。

したがって、リフレクションを使用してメソッドを呼び出すことができます。

var assembly = (Assembly) typeof(Assembly).GetTypeInfo()
    .GetDeclaredMethod("GetCallingAssembly")
    .Invoke(null, new object[0]);

Windowsストアアプリでこのメソッドが見えないのは、「これがなくなることを望んでいる」ためだと思います。

(この回答は、「すべきか」ではなく「できるか」にのみ関係します)。

于 2013-02-07T15:21:42.880 に答える
2

このメソッドは、WinRTアプリでは信頼性が低すぎるという理由だけでカットされました。WinRTの強力な設計目標は、異なる言語のランタイム環境間の相互運用をシンプルかつトラブルのないものにすることでした。これはうまく機能し、C#などの言語でWinRTコンポーネントを簡単に作成し、C++やJavascriptなどの管理されていない言語で記述されたアプリで使用することができます。

これはデスクトップ.N​​ETアプリでも可能ですが、[ComVisible]アセンブリにフォールバックするか、C ++ / CLI言語で混合モードアセンブリを作成する必要があるため、はるかに複雑です。このような場合にAssembly.GetCallingAssembly()を使用しても失敗しますが、プログラマーは特別なことを行うことをよく知っているため、失敗することが完全に予想されます。

これは、WinRTコンポーネントではさらに曖昧になります。特に、呼び出しが実際に別の.NETアセンブリから行われた場合は、失敗する必要はないためです。しかし、それが管理されていないコードから来たときは希望はありません。

このランダムな種類の失敗は、適切な回避策がなくてもまったくの惨めさです。したがって、メソッドはカットされました。PCLを使用することは可能な回避策ですが、Microsoftは過去に、そのような種類のハッコラマは非常に推奨されないことを厳しく警告しました。ゼロ以外のオッズでは、ストア検証手順によってキャッチされ、拒否されます。

于 2013-02-07T16:38:26.943 に答える