views:

110

answers:

2

In C# 3.0 you can use Expression to create a class with the following syntax:

var exp = Expression.New(typeof(MyClass));
var lambda = LambdaExpression.Lambda(exp);
object myObj = lambda.Compile().DynamicInvoke();

But how do you use Expression to create an Anonymous class?

//anonymousType = typeof(new{ Name="abc", Num=123});
Type anonymousType = Expression.NewAnonymousType???  <--How to do ?
var exp = Expression.New(anonymousType);
var lambda = LambdaExpression.Lambda(exp);
object myObj = lambda.Compile().DynamicInvoke();
+1  A: 

Since an anonymous type doesn't have a default empty constructor, you cannot use the Expression.New(Type) overload ... you have to provide the ConstructorInfo and parameters to the Expression.New method. To do that, you have to be able to get the Type ... so you need to make a "stub" instance of the anonymous type, and use that to get the Type, and the ConstructorInfo, and then pass the parameters to the Expression.New method.

Like this:

        var exp = Expression.New(new { Name = "", Num = 0 }.GetType().GetConstructors()[0], Expression.Constant("abc", typeof(string)), Expression.Constant(123, typeof(int)));
        var lambda = LambdaExpression.Lambda(exp);
        object myObj = lambda.Compile().DynamicInvoke();
Richard Hein
This is a clever solution. But usually the reason one needs to write something using expression trees (the API) is precisely because one *doesn't* have this info at compile-time. If one did, they would have used ordinary C# expressions in the first place.
Kirk Woll
@Kirk OPs code beg to differ. ANd there's plenty of situations where you'd know the type but still had to build an ExpressionTree. DynamicLinq-2-Sql for one
Rune FS
A: 

You're close, but you have to be aware that anonymous types don't have default constructors. The following code prints { Name = def, Num = 456 }:

Type anonType = new { Name = "abc", Num = 123 }.GetType();
var exp = Expression.New(
            anonType.GetConstructor(new[] { typeof(string), typeof(int) }),
            Expression.Constant("def"),
            Expression.Constant(456));
var lambda = LambdaExpression.Lambda(exp);
object myObj = lambda.Compile().DynamicInvoke();
Console.WriteLine(myObj);

If you don't have to create many instances of this type, Activator.CreateInstance will do just as well (it's faster for a few instances, but slower for many). This code prints { Name = ghi, Num = 789 }:

Type anonType = new { Name = "abc", Num = 123 }.GetType();
object myObj = Activator.CreateInstance(anonType, "ghi", 789);
Console.WriteLine(myObj);
Gabe
But, Type anonType = new { Name = "abc", Num = 123 }.GetType(); <--It is static code,not be dynamic code.
Flash
@Flash: If you are under the impression that the C# code `new { Name = "abc", Num = 123 }`, when used in a LINQ expression, creates a new type at run-time, then you are mistaken. The compiler creates the type at compile-time, and the generated Expression Tree is indistinguishable from one that uses a non-anonymous type.
Timwi
Flash: You want *dynamic anonymous* types? What do you intend to do with them?
Gabe