Выражения анонимного типа - PullRequest
0 голосов
/ 08 мая 2018

Ищет способ доступа к свойствам и значениям анонимного объекта в дереве выражений. В конечном итоге пары ключ / значение, передаваемые через анонимный объект, будут использоваться в качестве строк. Я нашел, как получить доступ к ключевой части, но у меня проблемы с поиском ценностной части.

Использование:

object.ExpressionBuilder<Company>(dc => new { DCCODE = dc.CompanyCode })

Метод:

ExpressionBuilder<T>(Expression<Func<T, object>> expr) 
{
   var propertyName = expr.Body.Type.GetProperties()[0].Name; //this gets "DCCODE" as a string

   var valueName = "dc.CompanyCode"; //looking for a way to get the matching value as either "CompanyCode" or "dc.CompanyCode"
}

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

Лучший подход к синтаксическому анализу выражений - создать пользовательский ExpressionVisitor. Конструкция анонимного типа представлена ​​узлом NewExpression, из которого можно получить доступ к членам и аргументам.

public class CustomExpressionVisitor : ExpressionVisitor
{
    protected override Expression VisitNew(NewExpression node)
    {
        Console.WriteLine($"{node.Members?.First().Name} {node.Arguments.FirstOrDefault()}");

        return base.VisitNew(node);
    }
}

Тогда вы можете использовать это так:

var expressionVisitor = new CustomExpressionVisitor();
expressionVisitor.Visit(expr);

Который печатает первое свойство со значением:

DCCODE dc.CompanyCode

Конечно, с этим классом вы можете делать любые преобразования, какие вам нравятся, в этом дереве выражений.

0 голосов
/ 08 мая 2018

Примечание : Я не могу заверить, что это всегда будет правильно, так как порядок может варьироваться, для определения этого следует обратиться к исходному коду. Однако с этим было весело играть.

var body = (NewExpression)expr.Body;
var zipped = body.Members.Zip(body.Arguments, (member, argument) => new KeyValuePair<MemberInfo, MemberExpression>(member, argument));

foreach (var zip in zipped)
{
    Console.WriteLine("Property name: {0}, property argument: {1}", zip.Key.Name, zip.Value.ToString());
}

Будет напечатано:

Имя свойства: DCODE, аргумент свойства: dc.CompanyCode

...