У меня есть функция, которая получает выражение в качестве параметра. Тип выражения Func<int?>
. Но когда выражение вычисляется, обнуляемое int распаковывается.
См. Следующий код:
using System;
using System.Linq.Expressions;
public class Program
{
public static void Main()
{
var asd = new Asd() { Id = 1 };
Do(() => asd.Id);
Console.Read();
}
private static void Do<T>(Expression<Func<T>> expr)
{
var tType = typeof(T);
var type = expr.Compile()().GetType();
Console.Write($"T = {tType.Name}, obj type = {type.Name}");
}
class Asd
{
public int? Id { get; set; }
}
}
Консоль показывает следующий вывод:
T = Nullable`1, obj type = Int32
Почему это происходит и как мне этого избежать?
К сожалению, я не могу предоставить dotnetfiddle, потому что этот код не работает в dotnetfiddle. может быть из-за выражений.
// Изменить:
Чтобы было понятно: мне нужно, чтобы свойство Id было типа int?
, и мне нужно скомпилировать и выполнить функцию. Проблема здесь возникает в большей части кода. Этот код является только минимально необходимым набором кода, чтобы иметь работоспособный пример.
С уважением
// Редактировать 2:
Оказалось, что мой маленький пример тоже выдает ошибки, которые позволяют мне думать, что он показывает мою реальную проблему. Но, конечно, это не так.
Я использовал GetType()
, чтобы показать вам, что возвращаемое значение функции имеет тип Nullable<int>
, а не int
. Согласно ссылкам, приведенным в комментариях, GetType () вызывает распаковку пустых значений и, таким образом, возвращает базовый тип.
Моей настоящей проблемой была другая, которая может иметь аналогичные причины.
Я использовал var valueExpr = Expression.Constant(valueFromImport);
для создания константного выражения со значением NULL int? valueFromImport = ...
. Позже я установил выражение, чтобы присвоить константе свойство, допускающее обнуляемость. Это терпит неудачу с исключением:
System.ArgumentException: "Expression of type 'System.Int32' cannot be used for assignment to type 'System.Nullable`1[System.Int32]'"
Проблема заключалась в том, что Expression.Constant
, похоже, также распаковывает значение NULL. Когда я использую var valueExpr = Expression.Constant(valueFromImport, typeof(T));
все работает как положено.