Wie verwende ich Expression, um einen anonymen Typ zu erstellen?

anonymous-types c# expression-trees linq

Frage

In C # 3.0 können Sie mit Expression eine Klasse mit der folgenden Syntax erstellen:

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

Aber wie verwenden Sie Expression, um eine anonyme Klasse zu erstellen?

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

Akzeptierte Antwort

Sie sind in der Nähe, aber Sie müssen wissen, dass anonyme Typen keine Standardkonstruktoren haben. Der folgende Code gibt { 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);

Wenn Sie nicht viele Instanzen dieses Typs erstellen müssen, wird Activator.CreateInstance genauso gut funktionieren (für einige Instanzen ist es schneller, für viele langsamer). Dieser Code druckt { Name = ghi, Num = 789 } :

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);

Beliebte Antwort

Da ein anonymer Typ keinen leeren Standardkonstruktor hat, können Sie die Expression.New(Type) -Überladung nicht verwenden. Sie müssen der Expression.New Methode die ConstructorInfo und Parameter bereitstellen. Um dies zu tun, müssen Sie in der Lage sein, den Typ ... zu erhalten, also müssen Sie eine "stub" -Instanz des anonymen Typs erstellen und diese verwenden, um den Type und die ConstructorInfo und dann die Parameter an die übergeben Expression.New Methode.

So was:

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();



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum