Suppose that you have the next code:

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

The argumentTypes array have two types : string and int... It's ok :)

But if I have the next code using Roslyn compiler:

            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 

Then the argumentTypes array shows two generic types like "Color j_TPar" and "Area j_TPar"... :(

My questions is: Why in the Roslyn example I can't get the correct argument types from Anonymous type?

How to get the "correct" argument types?

有帮助吗?

解决方案

I think it would be clearer if I asked the same question as you did, but used List<T> instead of the anomous type:

If I do new List<int>().GetType().GetGenericArguments(), I'm getting int as I expect. But if I look at the List type in mscorlib, it shows the generic type T, not int. Why?

Do you see the difference? In the first case, you have a constructed type (e.g. List<int>). But when you look at the assembly, you will see only the generic type definition (e.g. List<T>). The constructed type is created only when you actualy instatiate the generic type definition with some generic parameters.

If you're interested in knowing why are all anomous types generic at all, read Eric Lippert's article Why are anonymous types generic?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top