Return 如果泛型类型可为空则为 null

Return null if generic type is nullable

我正在编写一个函数来检查输出是否为 DBNull 和 returns null 如果泛型类型是否可为 null。如果不是,它只是抛出错误。

更新: 添加了所有建议

public T Get<T>(string key)
{
    int ordinal = reader.GetOrdinal(key);
    if (reader.IsDBNull(ordinal))
    {
        if (typeof(T).GetTypeInfo().IsValueType && Nullable.GetUnderlyingType(typeof(T)) == null) // isn't a nullable field
            throw new InvalidCastException();
        else return default(T);
    }
    return reader.GetFieldValue<T>(ordinal);
}

但是我不确定每个可为空的字段的 default(T) return 是否为空。如果现在有任何其他方法可以使它 return 为空?

是的,default(T) 是每个 T 的正确类型 null-like 值,实际上是 SomeType? / Nullable<SomeType>,所以呢你有应该工作正常。

您可能需要考虑 stringbyte[] 之类的东西 - 这些可以 来自数据库并且可以为空。

你可能还想想想,如果有人简单地犯了一个错误并在值为 <decimal> 时要求 <int>,错误应该是什么。那会导致 InvalidCastExceptionIDataReader 上有一个 IsDBNull() 方法可能比使用异常更合适。

最后:更喜欢 throw; 而不是 throw e;

就计算机资源而言,捕获和处理异常是一项极其昂贵的任务。您的方法将异常用作其逻辑流程的一部分。这是看待您要解决的问题的错误方式。

此外,您正在捕获特定的 InvalidCastException 异常。除了尝试强制转换空引用之外,其他情况下也可能发生此异常。你是 hiding/misrepresenting 一个潜在的有效错误;可能会让您花费很多时间进行令人沮丧的调试。

以下应该会为您提供与原始方法相同的行为,但不会在集成错误处理期间展开堆栈的开销。

public T Get<T>(string key)
{
    if(reader.IsDbNull(reader.GetOrdinal(key)))
    {
       //IF YOU SPECIFICALLY WANT TO THROW AN ERROR IF A VALUE TYPE
       //if (typeof(T).IsValueType) 
       //{ throw new InvalidCastException(); }
       return default(T);
    }

    return reader.GetFieldValue<T>(reader.GetOrdinal(key));
}