Я прошел некоторое время и бился головой о стену, а теперь искал различные фразы и ключевые слова, но я не могу найти ничего похожего на ответ, поэтому я надеюсь, что кто-то здесь может пролить свет.
В основном я работаю над глубоким погружением в манипулирование, создание и изменение деревьев выражений в C # 4.0
Я столкнулся со странной аномалией, которую я не могу понять
, если я что-то напишукак это
Expression<Func<string,string>> InsertAString = (Insert) => "This " + (Insert == "" ? "" : Insert + " ") + "That";
Когда я получаю отладку и смотрю на дерево выражений, оно выглядит примерно так:
- F (NodeType = Lambda)
- Body (NodeType)= Добавить)
- Слева (NodeType = Добавить)
- Слева (NodeType = Константа, Значение = "Это")
- Справа (NodeType = Условно)
- IfFalse (NodeType = Add)
- Слева (NodeType = Параметр, Имя = "Вставить")
- Справа (NodeType = Константа, Значение = "")
- IfTrue (NodeType = Constant, Value = "")
- Test (NodeType = Equal)
- Слева (NodeType = Параметр, Имя = "Вставить")
- Справа (NodeType = Константа, Значение = "")
- Справа (NodeType = Constant, Value = "That")
- Параметры (Count = 1)
- Параметры [0] (NodeType= Параметр, Имя = "Вставить")
Я могу позвонить
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, не обработанное
Бинарный оператор Add не являетсяопределенные для 'System.String' и 'System.String'
Теперь, почему это так?
Почему, когда я позволяю C # преобразовать лямбда-выражение в выражение, оно, очевидно, использует AddNodeType, и дисплей Types показывает, что он определенно использует System.String, но когда я пытаюсь сделать то же самое вручную, он не позволит продолжить код?
В качестве заключительного замечания я даже попробовал следующее:
BinaryExpression InsertPlusSpace = Expression.MakeBinary( ExpressionType.Add,Insert,Space);
Та же ошибка.
Мне любопытно, почему, по крайней мере, с тем, что мне удалось найти, работает конкатенация строк в деревьях выраженийТолько если вы не пытаетесь построить дерево выражений вручную, которое добавляет константы и переменные типа System.String.
Заранее всем спасибо за ответы.