3

次のコードがあるとします。

        var house = new {Color = "White", Area = 150};
        var typeHouse = house.GetType();
        var argumentTypes = typeHouse.GetGenericArguments();

argumentTypes配列には、string と int の 2 つのタイプがあります。問題ありません :)

しかし、Roslyn コンパイラを使用した次のコードがあるとします。

            var tree = SyntaxTree.ParseText(@"
            namespace TestRoslyn {
                public class MyClass {
                    public void GetHouse(){
                        var house = new {Color = 'W', Area = 150};
                    }
                }
            }");

        byte[] assembly;
        var compiler = Compilation.Create("Test", new CompilationOptions(outputKind: OutputKind.DynamicallyLinkedLibrary,
                                                                 usings: new[] { "System" }))
            .AddSyntaxTrees(tree)
            .AddReferences(new MetadataFileReference(typeof(object).Assembly.Location));

        using (var stream = new MemoryStream())
        {
            var result = compiler.Emit(stream);
            if (!result.Success)
                throw new Exception("You have an error! :( ");
            assembly = stream.ToArray();
        }
        Type[] types = Assembly.Load(assembly).GetTypes();
        var argumentTypes = types[0].GetGenericArguments(); //types [0] returns the <>f__AnonymousType 

次に、argumentTypes配列は、「Color j_ TPar」と「Area j _TPar」のような 2 つのジェネリック型を示します... :(

私の質問は次のとおりです。Roslyn の例で、匿名型から正しい引数の型を取得できないのはなぜですか?

「正しい」引数タイプを取得するには?

4

1 に答える 1

6

私があなたと同じ質問をした場合、より明確になると思いますがList<T>、匿名タイプの代わりに使用されます:

もしそうならnew List<int>().GetType().GetGenericArguments()、私はint期待通りになっています。しかしList、mscorlib の型を見ると、Tではなくジェネリック型が表示されintます。なんで?

違いがわかりますか?最初のケースでは、構築された型(例: List<int>) があります。しかし、アセンブリを見ると、ジェネリック型定義のみが表示されます(例: List<T>)。構築された型は、いくつかのジェネリック パラメーターを使用してジェネリック型定義を実際にインスタンス化した場合にのみ作成されます。

すべての無名型がジェネリックである理由を知りたい場合は、Eric Lippert の記事Why are anonymous types generic?を読んでください。

于 2013-09-25T21:56:16.207 に答える