我正在编写一个函数来检查输出是否为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?
答案 0 :(得分:5)
是的,default(T)
是null
的正确类型 - 每个T
的价值实际上是SomeType?
/ Nullable<SomeType>
,所以你有什么应该工作正常。
您可能希望考虑string
和byte[]
之类的内容 - 这些也来自数据库,可以为空。
您可能还想考虑如果有人犯了错误,错误应该是什么,并在值为<int>
时询问<decimal>
。这会导致InvalidCastException
。 IsDBNull()
上有一个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));
}