Nicolocodev Nicolocodev - 2 months ago 20
C# Question

Get Generic arguments type of anonymous type in Roslyn assembly

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?

Answer

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?