У меня есть анонимный тип, который динамически создается как класс во время выполнения. Пример:
ctx.Select(x => new { .name = x.name }) //the expression is an anonymous.
//Gets translated to a new type of class-name "dynType" with IL.
//new dynType { .name = x.name }
Проблема в том, что я перестраиваю исходное выражение из оператора ctx.Select. У меня есть ExpressionVisitor, который получает тело из оператора Select. Но я просто не знаю, как превратить NewExpression типа Anonymous в динамически создаваемый тип с именем dynType?
Это в методе VisitNew:
var bindings = new List<MemberAssignment>();
foreach (prop in dynType.GetProperties()) {
var xOriginal = Expression.[Property](Expression.Parameter(dynType,"x");
bindings.Add(Expression.Bind(prop, xOriginal);
}
//This returns a MemberInit. How can I return a NewExpression instead?
return Expression.MemberInit(Expression.[New](dynType), bindings)
И переданное выражение в качестве параметра метода VisitNew изначально содержит выражение NewExpression типа Anonymous. Таким образом, на самом деле моя цель состоит в том, чтобы изменить это выражение NewExpression на тип "dynType".
MemberInit содержит выражение NewExpression, имеющее тип dyntype, но свойство Arguments пусто. Это смущает меня. Насколько я понимаю, свойство Arguments должно содержать MemberAssignments?
Надеюсь, это имеет смысл? В противном случае я сделаю все возможное, чтобы уточнить.
Поэтому я хочу преобразовать (см. Изображение) аргумент с индексом 1 в типизированное выражение NewExpression, но я не могу понять это правильно.
Или это возможно? Я смотрю на EF Core, и они, кажется, строят его на базе StringBuilder ...
public virtual string Lambda(IReadOnlyList<string> properties)
{
Check.NotNull(properties, nameof(properties));
var builder = new StringBuilder();
builder.Append("x => ");
if (properties.Count == 1)
{
builder
.Append("x.")
.Append(properties[0]);
}
else
{
builder.Append("new { ");
builder.AppendJoin(", ", properties.Select(p => "x." + p));
builder.Append(" }");
}
return builder.ToString();
}