特定のコンパイルで型のコレクションを取得しようとすると、どの方法で問題にアプローチするかについて、私は混乱してしまいました。基本的に、結果を返すように見えるメソッドは結果を返さず、逆もまた同様です。以下は、デバッグ セッションのイミディエイト ウィンドウからの出力です。ここappCompilation
で、タイプはCompilation
(natch) です。
**appCompilation.GlobalNamespace.GetMembers()**
Count = 14
[0]: "Namespace Registration"
[1]: "Namespace Payments"
[2]: "Namespace Foo"
[3]: "NamedType <Module>"
[4]: "NamedType <Module>"
[5]: "NamedType <Module>"
[6]: "NamedType <Module>"
[7]: "NamedType <Module>"
[8]: "NamedType <Module>"
[9]: "NamedType <Module>"
[10]: "Namespace Conference"
[11]: "Namespace System"
[12]: "NamedType <>f__AnonymousType0<<OrderId>j__TPar>"
[13]: "Namespace Infrastructure"
**appCompilation.GlobalNamespace.GetTypeMembers()**
{System.Linq.Enumerable.OfTypeIterator<Roslyn.Compilers.CSharp.NamedTypeSymbol>}
source: null
**appCompilation.GlobalNamespace.GetNamespaceMembers()**
{System.Linq.Enumerable.OfTypeIterator<Roslyn.Compilers.CSharp.NamespaceSymbol>}
source: null
だから私の質問はこれです: ==.GetTypeMembers()
の Symbol を呼び出すと、null になります。同じシンボルを呼び出すと、null も取得されます。それでも、呼び出すと、名前空間と型が豊富に取得されます!Kind
Namespace
.GetNamespaceMembers()
.GetMembers()
さらに奇妙なことに、このステートメントをウォッチ ウィンドウに配置すると、空でも null でもない結果が得られます。
appCompilation.GlobalNamespace.GetNamespaceMembers(), results
おそらく関連: クエリの実行が期待どおりに開始されないようですが、どのように、またはなぜそれについて心配する必要があるのか さえ正確にはわかりません...呼び出す.ToList()
と実行がトリガーされることがあります。多くのメソッドはCancellationToken
パラメーターを提供しますが、それらはすべて同期的に実行されると考えていました。また、さまざまなメソッドがまたはのいずれかGetXXX()
を返すという問題もあります。読み取り専用は、IEnumerable と同じ方法で LINQ 拡張メソッドから同じ動作を取得していないようです。ReadOnlyArray
IEnumerable
デバッグ出力の表面スキャンから判断すると、それは次のようGetTypeMembers
に見えます。多分それは物事がつまらなくなっているその翻訳にありますか?GetMembers()
.OfType<>
いずれにせよ、クエリへのアクセスと実行の不一致は非常に苦痛でした。そのため、物事が非常に非決定的であるように見える原因となっている何が欠けているのかを誰かが理解するのを手伝ってくれることを願っています.
EDIT:少し繰り返した後、シンボルツリーを介して再帰的な検索を行うだけでよいことがわかりました。そのクエリ構文は、ラムダ式よりもはるかに簡単なアプローチになる場合があります...そして、そうです-PEBKAC、それ以来イミディエイト ウィンドウは、デバッグ作業を支援する以上に妨げていたようです。
与えられたコンパイルから、3 つの名前空間の入れ子程度までのすべての型を取得する最終的な Passing クエリ サンプル (これらのケースをカバーするには、さらにテストが必要です):
これから (そして、これは他のいくつかの試みよりもはるかに優れています!)
appCompilation.Assembly.GlobalNamespace.GetNamespaceMembers()
.SelectMany(x => x.GetNamespaceMembers().Select(y => y.GetNamespaceMembers()))
.SelectMany(x => x, (symbols, symbol) => symbol.GetTypeMembers())
.SelectMany(x => x);
これに(まだ完全に再帰的ではありませんが、今のところは十分です):
from glob in appCompilation.Assembly.GlobalNamespace
.GetMembers()
.OfType<NamespaceOrTypeSymbol>()
from childNs in glob
.GetMembers()
.OfType<NamespaceSymbol>()
from childTypes in childNs
.GetTypeMembers()
select childTypes;