Подтвердить что ты не робот

С# Reflection: Как получить тип Nullable <int>?

Я хочу сделать что-то вроде этого:

switch( myObject.GetType().GetProperty( "id") )
{
    case ??: 
        // when Nullable<Int32>, do this
    case ??:
        // when string, do this
    case ??:
        // when Nullable<bool>, do this

Какой путь в объекте .GetType() будет иметь строковое имя типа данных, которое я мог бы сравнить, используя оператор case? Мне нужно знать тип, поэтому у меня может быть одна из многих Convert.ToInt32 (строка), которая будет устанавливать значение myObject с помощью Reflection.

4b9b3361

Ответ 1

Обновление: похоже, что С# 7 будет поддерживать включение Type, как пытался этот вопрос. Это немного отличается, хотя так что следите за синтаксическими минами.

Вам не требуется имя строки для сравнения:

if (myObject.GetType().GetProperty("id").PropertyType == typeof(Nullable<Int32>))
    // when Nullable<Int32>, do this
else if (myObject.GetType().GetProperty("id").PropertyType == typeof(string))
    // when string, do this
else if (myObject.GetType().GetProperty("id").PropertyType == typeof(Nullable<bool>))
    // when Nullable<bool>, do this

Ответ 2

Я использовал следующий тип кода, чтобы проверить, является ли тип нулевым и получить фактический тип:

if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
    return Nullable.GetUnderlyingType(type);
}

Если тип является, например, Nullable этот код возвращает int-часть (базовый тип). Если вам просто нужно преобразовать объект в определенный тип, вы можете использовать метод System.Convert.ChangeType.

Ответ 3

Вопрос очень запутан. Является ли "myObject" объектом, который может быть обнуляемым int? Или это свойство "id" возможно с типом nullable int?

Если первое, на ваш вопрос нельзя ответить, потому что он предполагает ложь. Нет такой вещи, как вставка с номером в квадрат с нулевым значением. Я отмечаю, что все ответы, предлагающие if (myobject.GetType() == typeof(int?)), поэтому неверны; условие никогда не будет истинным.

Когда вы конвертируете nullable int в объект, либо он становится пустой ссылкой (если значение nullable int не имеет значения), либо оно становится вложенным int. Невозможно определить, содержит ли объект int с нулевым значением, поскольку объект никогда не содержит nullable int.

Если последнее, сравните тип свойства с typeof(int?). Вы не можете использовать переключатель; для случаев переключения могут использоваться только константы, а типы не являются константами.

Все, что сказал, это плохой запах кода. Почему вы используете отражение в первую очередь?

Ответ 4

В .net экземпляры типов значений являются просто наборами битов, без связанной информации типа. Однако для любого типа значений, отличного от Nullable<T>, система также автоматически генерирует соответствующий тип класса, который происходит от System.ValueType. Расширяющееся преобразование существует от типа значения к автоматически генерируемому типу класса и сужению преобразования от автоматически генерируемого типа класса к типу значения. В случае Nullable<T> нет соответствующего автоматически генерируемого типа класса с преобразованиями в/из типа значения; вместо этого расширяющиеся преобразования существуют в обоих направлениях между Nullable<T> и типом класса, связанным с T.

Насколько я могу судить, это странное поведение было реализовано, чтобы позволить сравнения между null и пустым Nullable<T> возвращать true.

Ответ 5

Как сказал @Cody Grey, если утверждения, вероятно, будут лучшим способом

var t = myObject.GetType();

if (t == typeof(Nullable<int>))
{ }
else if (t == typeof(string))
{}
else if (t==typeof(Nullable<bool>))
{}