Как сделать Nullable.GetUnderlyingType, не затрагивая возможные проблемы с нулевыми ссылками

#c# #nullable-reference-types

#c# #nullable-reference-types

Вопрос:

Я пытаюсь модернизировать старую библиотеку для поддержки ссылочного типа с нулевым значением.

Этот бит оказывается сложным. Я хочу получить тип объекта. Если это обнуляемый тип, то мне нужен базовый тип..

 Type optionalType = //(a type that could be anything, including nullable types.)

if (optionalType.IsGenericType amp;amp; optionalType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
    optionalType = Nullable.GetUnderlyingType(optionalType);
}
  

Это не устраивает, потому GetUnderlyingType что вернет null, если вы передадите ему значение, не равное нулю. Компилятор показывает ошибку CS8600: Converting null literal or possible null value to non-nullable type. , но я уже защитился от этого.

Есть ли способ сделать это лучше, или я должен разрешить нули на моем optionalType ?

Комментарии:

1. Ваше условие дублирует точные проверки, которые Nullable.GetUnderlyingType выполняются. Весь if оператор / блок может быть заменен этим: optionalType = Nullable.GetUnderlyingType(optionalType) ?? optionalType; То есть, если Nullable.GetUnderlyingType возвращает null, вернитесь к значению, которое у вас уже есть.

Ответ №1:

Если вы посмотрите на исходный код Nullable.GetUnderlyingType , вы заметите, что он выполняет те же проверки, что и вы. На самом деле это делает больше:

      public static Type GetUnderlyingType(Type nullableType) {
        if((object)nullableType == null) {
            throw new ArgumentNullException("nullableType");
        }
        Contract.EndContractBlock();
        Type result = null;
        if( nullableType.IsGenericType amp;amp; !nullableType.IsGenericTypeDefinition) { 
            // instantiated generic type only                
            Type genericType = nullableType.GetGenericTypeDefinition();
            if( Object.ReferenceEquals(genericType, typeof(Nullable<>))) {
                result = nullableType.GetGenericArguments()[0];
            }
        }
        return resu<
    }
  

Как говорит @madreflection, вы можете заменить весь этот фрагмент кода просто:

 optionalType = Nullable.GetUnderlyingType(optionalType) ?? optionalType;