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>
,所以呢你有应该工作正常。
您可能需要考虑 string
和 byte[]
之类的东西 - 这些可以 也 来自数据库并且可以为空。
你可能还想想想,如果有人简单地犯了一个错误并在值为 <decimal>
时要求 <int>
,错误应该是什么。那会导致 InvalidCastException
。 IDataReader
上有一个 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));
}
我正在编写一个函数来检查输出是否为 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>
,所以呢你有应该工作正常。
您可能需要考虑 string
和 byte[]
之类的东西 - 这些可以 也 来自数据库并且可以为空。
你可能还想想想,如果有人简单地犯了一个错误并在值为 <decimal>
时要求 <int>
,错误应该是什么。那会导致 InvalidCastException
。 IDataReader
上有一个 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));
}