如果泛型类型可为空,则返回null

时间:2017-12-06 23:41:43

标签: c# generics nullable default-value mysql-connector

我正在编写一个函数来检查输出是否为DBNull,如果泛型类型可以为空,则返回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)是否为每个可空字段返回null。如果现在有任何其他方法使它返回null?

2 个答案:

答案 0 :(得分:5)

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

您可能希望考虑stringbyte[]之类的内容 - 这些来自数据库,可以为空。

您可能还想考虑如果有人犯了错误,错误应该是什么,并在值为<int>时询问<decimal>。这会导致InvalidCastExceptionIsDBNull()上有一个IDataReader方法可能比使用异常更合适。

最后:首选throw;throw e;

答案 1 :(得分:2)

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

此外,您将特别捕捉InvalidCastException例外情况。除了尝试转换空引用之外的其他情况,可能会发生此异常。您隐藏/歪曲可能有效的错误;可能会花费你数小时令人沮丧,令人头疼的调试。

以下内容应该为您提供与原始方法相同的行为,但没有在集成错误处理期间解除堆栈的开销。

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));
}