4

組み込み REPL で Roslyn スクリプト API を使用しています。時々、現在のセッションで定義されている変数、他のすべての定義 (クラス、インターフェイスなど) の定義、およびどの参照とインポートされた名前空間を知る必要があります。

APIでそのような情報を提供できるものは何も見つかりませんでした。どこかにあることは知っています。

Dose Scripting API は、毎回更新されるインメモリ アセンブリなど、いくつかの異常な実装を使用していますか? もしそうなら、そのアセンブリにアクセスする方法。

4

1 に答える 1

6

Roslyn 固有の API があるかどうかはわかりませんが、Reflection を使用して情報を取得できるようです。ちょっとした雑用です。Visual Studio で REPL を使用して、状況を近似しています。

using System.Reflection;

Assembly.GetExecutingAssembly().DefinedTypes

ループの反復ごとに型があり、定義された追加のクラスがいくつかあることを示しています。幸いなことに、Submissionタイプには番号が付けられており、後者の提出ほど番号が大きくなります。つまり、 のSubmission#11後に続きSubmission#5ます。

REPL で定義された変数は、それが定義されたループの実行に対応するセッション タイプのフィールドとして表示されます。型で定義されたすべての変数を表示する呼び出しは、次のようになります。

chosenType.GetFields(BindingFlags.Instance | BindingFlags.Public)

Roslyn REPL を使用すると、変数を再宣言して、以前に宣言した変数を新しい呼び出し元からマスクできます。ここで、「セッション」をすべての送信のスタックと見なします (最も古いものが一番下にあります)。スタックをたどると、特定のフィールド名の最初の出現が、REPL 内のその名前を持つアクティブな変数になります。取得されたフィールド情報は、名前に加えてタイプを提供します。

以下は、セッション内で宣言されたすべての変数を確認する方法を示すセッション (出力を含む) の例です。

> using System.Reflection;
> var a = 1; 
> var b = "c";
> var c = from type in Assembly.GetExecutingAssembly().DefinedTypes.Reverse()
      from variable in type.GetFields(BindingFlags.Instance | BindingFlags.Public)
      select variable;
> foreach (var info in c ) { 
     if (info.FieldType != typeof(Roslyn.Services.InteractiveHostObject)) {
         Console.WriteLine(info);
     }
  }
System.Collections.Generic.IEnumerable`1[System.Reflection.FieldInfo] c
System.String b
Int32 a

同じ名前が 2 回表示された場合は、最初にリストされた名前がセッションで使用可能な名前になります。上記は、返される型がたまたま古いものから新しいものへと並べられるという事実を利用しています。確実にするために、おそらく自分で並べ替えたいと思うでしょう。

なんらかの理由で (おそらくバグ?) foreach ループ内で if ステートメントを使用する必要があり、LINQ where 句を使用しても期待どおりの結果が得られません。

や など、探したいものに応じて便利なリフレクション メソッドが他にもたくさんありGetMethodsますGetEvents。すべてが必要な場合は、GetMembers See Type Methodsがあります。

誰かがもっと簡単な方法を提供してくれることを願っています。

于 2012-10-24T21:44:41.363 に答える