Деревья выражений работают на более низком уровне по сравнению с обычным исходным кодом - вы можете думать о них как о работающих на уровне вывода компилятора, а не ввода . Поэтому, хотя в C # существует неявное преобразование из int
в int?
, это преобразование должно быть представлено в IL всякий раз, когда компилятор использует его для обычного метода ... поэтому оно также должно присутствовать в представлении дерева выражений.
Сказав это, ваш пример несколько неясен, учитывая, что вы пытаетесь использовать int
(а именно ItemTypeValue.Value
) в качестве значения для константы int?
, и мы не знаем, что это за тип из свойства ItemType
- либо.
Короткий, но завершенный пример того, что вы ожидаете от работы, действительно поможет.
РЕДАКТИРОВАТЬ: Хорошо, я думаю, что я с тобой сейчас. Проблема в том, что если вы используете
int? foo = 1;
Expression.Constant(foo);
, тогда это вызывает Expression.Constant(object)
, что ограничивает значение foo
. В этот момент Expression.Constant
не может сказать, что изначально это был int?
, потому что теперь это int
в штучной упаковке. Так работает бокс .NET:
int? foo = 1;
object o = foo;
Console.WriteLine(o.GetType()); // Prints System.Int32
Эта перегрузка Expression.Constant
определяет общий тип выражения по заданному значению - поэтому он создает выражение int
, тогда как вы действительно хотите выражение int?
.
Чтобы правильно поддерживать информацию о типе, вы должны использовать перегрузку, которая позволяет вам указать тип:
int? foo = 1;
Expression.Constant(foo, typeof(int?));
Из вашего вопроса все еще не совсем ясно, какой код работает, а какой нет, но, надеюсь, это поможет ...