GetType для nullable int возвращает так же, как GetType для int - PullRequest
0 голосов
/ 07 января 2019

У меня есть функция, которая получает выражение в качестве параметра. Тип выражения 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)); все работает как положено.

1 Ответ

0 голосов
/ 07 января 2019

Что вы подразумеваете под "int is unpacked"? Результат выражения все еще имеет тип int?, но вы не можете получить его с помощью отражения, что является ожидаемым поведением. Цитирование msdn для Nullables :

Вызов GetType для типа Nullable приводит к выполнению операции бокса, когда тип неявно преобразуется в Object. Поэтому GetType всегда возвращает объект Type, который представляет базовый тип, а не тип Nullable.

В любом случае, в чем ваша основная проблема? Результат имеет правильный тип, и вы все равно можете получить его с помощью typeof(T). Результат GetType не должен мешать вам.

...