Я прошел и бился головой об стену некоторое время, теперь искал различные фразы и ключевые слова, но я не могу найти ничего близкого к ответу, поэтому я надеюсь кто-то здесь может пролить свет.
В основном я работаю над довольно глубоким погружением в управление, создание и изменение деревьев выражений в C # 4.0
Я наткнулся на странную аномалию, я не могу понять
, если напишу что-то вроде этого
Expression<Func<string,string>> InsertAString = (Insert) => "This " + (Insert == "" ? "" : Insert + " ") + "That";
Когда я отлаживаю и смотрю на дерево выражений, оно выглядит примерно так
Я могу позвонить
Console.WriteLine(InsertAString.Compile()("Is Something In-between"));
И я выхожу, как и ожидал
«Это нечто среднее между этим»
Сейчас если я попытаюсь перестроить его вручную, используя статические методы базового класса Expression, я столкнусь с интересной проблемой. (Я разбил каждый шаг на отдельное выражение для целей отладки)
ParameterExpression Insert = Expression.Parameter(typeof(object), "Insert");
ConstantExpression This = Expression.Constant("This ");
ConstantExpression That = Expression.Constant("That");
ConstantExpression Space = Expression.Constant(" ");
ConstantExpression NoCharacter = Expression.Constant("");
BinaryExpression InsertPlusSpace = Expression.Add(Insert,Space);
BinaryExpression InsertEqualsNoCharacter = Expression.Equal(Insert,NoCharacter);
ConditionalExpression InsertPlusSpaceOrNothing = Expression.IfThenElse(InsertEqualsNoCharacter,NoCharacter,InsertPlusSpace);
BinaryExpression ThisPlusInsertPlusSpaceOrNothing = Expression.Add(This,InsertPlusSpaceOrNothing);
BinaryExpression ThisPlusInsertPlusSpaceOrNothingPlusThat = Expression.Add(ThisPlusInsertPlusSpaceOrNothing, That);
Lambda Lambda = Expression.Lambda(ThisPlusInsertPlusSpaceOrNothingPlusThat, Middle);
Expression<Func<string,string>> InsertAString = Lambda as Expression<Func<string,string>>
Это на основе значений сгенерированного дерева выражений выше воссоздает такое же базовое дерево выражений, как указано выше (по крайней мере, с тем же «взглядом»)
Все проходит нормально, пока вы не дойдете до этой строки
BinaryExpression InsertPlusSpace = Expression.Add(Insert,Space);
. Компилятор выдает InvalidOperationException было unhandled
Бинарный оператор Add не определен для System.String и 'System.String'
Почему это так?
Почему, когда я позволяю C # преобразовывать лямбда-выражение в выражение, он явно использует Add NodeType, а отображение типов показывает, что он определенно использует System.String, когда я попробуйте сделать то же самое вручную, это не позволит продолжить код?
В заключение я даже пробовал следующее:
BinaryExpression InsertPlusSpace = Expression.MakeBinary( ExpressionType.Add,Insert,Space);
Та же ошибка.
Мне любопытно, почему это кажется хотя бы с тем, что я пока удалось обнаружить, что конкатенация строк в деревьях выражений работает только в том случае, если вы не пытаетесь вручную построить дерево выражений, которое добавляет константы и переменные типа System.String.
Заранее всем спасибо за ответы.