32

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();
Richard Anthony Hein
  • 10,550
  • 3
  • 42
  • 62
Flash
  • 1,615
  • 4
  • 17
  • 23
  • Possible dup of: http://stackoverflow.com/questions/606104/linq-expression-tree-question – Kirk Woll Sep 18 '10 at 06:20
  • 1
    @Flash, this is not possible, at least not directly. The compiler does a lot of "magic" for you when you create anonymous types -- it's syntactic sugar for actually declaring a genuine C# class with a bunch of properties. The compiler just does all this for you. There is no expression tree type that actually does all this for you automatically. If you look at the link I referenced, it provides a workaround. However, it uses Reflection.Emit, which is not for the feint of heart. – Kirk Woll Sep 18 '10 at 06:23
  • 1
    Kirk: The OP wants to *construct* an anonymous class, not *create* one from scratch. As long as he knows at compile time what the properties' names and types are, he can get the compiler to create the type for him and all he has to do is figure out how to instance it up. – Gabe Sep 18 '10 at 06:34
  • 1
    @Gabe, I don't agree with your interpretation of what the OP wanted, but I suppose we'll see. ;) – Kirk Woll Sep 18 '10 at 06:36
  • Kirk: Based on the OP's example of `var exp = Expression.New(typeof(MyClass));` it would appear as though his notion of "create a class" is really "create an instance of an existing class". If he wanted to create a new class, it wouldn't make sense for it to be anonymous. – Gabe Sep 18 '10 at 06:45
  • 1
    @Gabe, I disagree. He commented out his definition of the class presumably to find a way to do that with expression trees. Furthermore, the title of this post is "How to use Expression to build an Anonymous Type?" I have never used the verb to "build" to refer to "instantiation". – Kirk Woll Sep 18 '10 at 06:48
  • Kirk: While you do have a good point, it makes no sense to create a *new* anonymous class (why would you care that it's anonymous), and there's no way to use Expression trees to create any sort of class (anonymous or not). The OP would have to greatly elaborate on his purpose to really be able to figure out what he wants. – Gabe Sep 18 '10 at 06:57
  • As others have implied `Expression.New(typeof(MyClass));` is not creating a class but an object instance of a given type. Do you need an expression tree to create an object of an Anonymous type? – Rune FS Sep 18 '10 at 07:58

3 Answers3

26

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
  • 84,912
  • 12
  • 139
  • 238
  • 6
    But, Type anonType = new { Name = "abc", Num = 123 }.GetType(); <--It is static code,not be dynamic code. – Flash Sep 18 '10 at 07:54
  • 3
    @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 Sep 18 '10 at 08:28
  • Flash: You want *dynamic anonymous* types? What do you intend to do with them? – Gabe Sep 18 '10 at 12:24
  • 5
    I personally prefer to use `Type anonType = new { Name = default(string), Num = default(int) }.GetType();` when defining the anonymous type as I find it makes it clearer to separate the definition from the use. – Lukazoid Feb 14 '12 at 12:14
  • Usually, you would make method containing this code generic, so that one of it's paramters of type T would be anonymous object. You could then use `typeof(T).GetType()` instead of inlining `new {...}` in method body. – ghord May 18 '13 at 16:17
  • @ghord `typeof(T).GetType()` will always return `typeof(System.Type)`, which would be pretty useless IMO ;) – Mike Marynowski Jul 11 '13 at 23:56
  • @MikeMarynowski You are right of course. It should be `typeof(T)`. – ghord Jul 12 '13 at 07:22
  • I would assume the second method using Activator.CreateInstance is going to be much faster than the dynamic function call using DynamicInvoke. – nawfal Sep 29 '15 at 11:58
  • @nawfal: The `DynamicInvoke` call will be faster; the slow part is compiling the function that it calls in the first place. – Gabe Oct 30 '15 at 04:34
  • @Gabe Yes I am talking of running the compiled delegate. Even then DynamicInvoke call is going to be slower, just my hunch. Did you test it? – nawfal Oct 30 '15 at 04:58
  • @Gabe you're right, I tested them, DynamicInvoke is indeed faster: [1st method](http://volatileread.com/utilitylibrary/snippetcompiler?id=41088), [2nd method](http://volatileread.com/utilitylibrary/snippetcompiler?id=41087). As I have stated in [my answer](http://volatileread.com/utilitylibrary/snippetcompiler?id=41089), you can totally avoid DynamicInvoke which will be even faster, besides being more flexible. – nawfal Oct 30 '15 at 05:25
7

You can avoid using DynamicInvoke which is painfully slow. You could make use of type inference in C# to get your anonymous type instantiated generically. Something like:

public static Func<object[], T> AnonymousInstantiator<T>(T example)
{
    var ctor = typeof(T).GetConstructors().First();
    var paramExpr = Expression.Parameter(typeof(object[]));
    return Expression.Lambda<Func<object[], T>>
    (
        Expression.New
        (
            ctor,
            ctor.GetParameters().Select
            (
                (x, i) => Expression.Convert
                (
                    Expression.ArrayIndex(paramExpr, Expression.Constant(i)),
                    x.ParameterType
                )
            )
        ), paramExpr).Compile();
}

Now you can call,

var instantiator = AnonymousInstantiator(new { Name = default(string), Num = default(int) });

var a1 = instantiator(new object[] { "abc", 123 }); // strongly typed
var a2 = instantiator(new object[] { "xyz", 789 }); // strongly typed
// etc.

You could use the AnonymousInstantiator method to generate functions to instantiate any anonymous type with any number of properties, just that you have to pass an appropriate example first. The input parameters have to be passed as an object array. If you worry boxing performance there then you have to write a custom instantiator which accepts just string and int as input parameters, but the use of such an instantiator will be a bit more limited.

nawfal
  • 70,104
  • 56
  • 326
  • 368
6

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();
nawfal
  • 70,104
  • 56
  • 326
  • 368
Richard Anthony Hein
  • 10,550
  • 3
  • 42
  • 62
  • 6
    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 Sep 18 '10 at 06:33
  • @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 Sep 18 '10 at 08:01
  • Just nitpicking, anonymous types have empty constructors if the anonymous type is `new { }` :) – nawfal Aug 19 '15 at 12:23
  • 1
    @KirkWoll Actually, often the point is that you *do* know the type information at compile time, and your code can use said information to construct and compile some wonderfully elaborate expression trees that would be a nightmare to code and maintain by hand. They can be the best compromise between simplicity/expressiveness and performance when you need to do the same sort of complicated thing dozens or hundreds of times in novel configurations. – Daniel Sep 03 '21 at 05:30