Как написать новый список <CustomClass>() в дереве выражений? - PullRequest
0 голосов
/ 10 мая 2018

Я хочу знать, как мы можем представить ниже код C # в дереве выражений.

var list = new List<CustomClass>(); 
list.add(new CustomClass());

где CustomClass - некоторый класс сложного типа.

Например, как можно инициализировать массив с помощью Expression.NewArrayInit

Спасибо

Ответы [ 2 ]

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

Вместо использования двух отдельных операторов я бы предложил использовать инициализатор коллекции.В этот момент вы можете заставить компилятор построить дерево выражений для вас, потому что это одно выражение:

Expression<Func<List<CustomClass>>> expr =
    () => new List<CustomClass> { new CustomClass() };

Также более вероятно, что инструменты, использующие деревья выражений (например, поставщики LINQ), поймутtree.

Сгенерированное дерево использует Expression.ListInitExpression в качестве списка-эквивалента Expression.NewArrayInit.

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

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

Код, который вы спросили, это:

// List<CustomClass> foo;
var listV = Expression.Variable(typeof(List<CustomClass>), "foo");

// new List<CustomClass>()
var newL = Expression.New(typeof(List<CustomClass>));

// foo = new List<CustomClass>()
var assV = Expression.Assign(listV, newL);

// new CustomClass()
var newEl = Expression.New(typeof(CustomClass));

// foo.Add(new CustomClass())
var addEl = Expression.Call(listV, "Add", null, newEl);

var be = Expression.Block(new[] { listV }, assV, addEl);

Обратите внимание, что я даю вам блочное выражение ... Вы можете поместить его в большее выражение (или создать на его основе лямбда-выражение), но оно не может быть запущено напрямую (потому что это не лямбда-выражение )

Пример лямбда-выражения:

var be = Expression.Block(new[] { listV }, assV, addEl, listV);

var lambda = Expression.Lambda<Func<List<CustomClass>>>(be);
var func = lambda.Compile();

List<CustomClass> res = func();

(обратите внимание, что я меняю переменную be)

...