如何 Nullable.GetUnderlyingType 而不会遇到可能的空引用问题

How to Nullable.GetUnderlyingType without hitting possible null reference issues

我正在尝试对旧库进行现代化改造以支持可为 null 的引用类型。

事实证明这一点很有挑战性。我想获取对象的类型。如果它是可空类型,那么我想要基础类型..

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

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

这并不令人满意,因为如果您传递一个不可为 null 的参数,GetUnderlyingType 将 return null。编译器显示错误 CS8600: Converting null literal or possible null value to non-nullable type. 但我已经对此有所防范。

有没有更好的方法,或者我必须在 optionalType 上允许空值?

如果您查看 Nullable.GetUnderlyingType 的源代码,您会发现它执行的检查与您正在执行的检查相同。事实上它做得更多:

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

正如@madreflection 所说,您可以用简单的方式替换整个代码块:

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