c# – 取消装箱-1并使用泛型强制转换为Nullable会产生InvalidCastException
作者:互联网
在this SO post中,我找到了一个通用扩展方法,如果SqlDataReader读取的值为null或DBNull.Value,则返回默认值,否则返回正确转换的值.我这样实现了:
public static T GetValueOrDefault<T>(this SqlDataReader reader, string columnName, T defaultValue = default(T))
{
object val = reader[columnName];
if (val == null || val == DBNull.Value)
{
return defaultValue;
}
return (T)val;
}
下面提到的上面提到的帖子中的方法没有使用正确的语法,但是仍然建议这也适用于可以为空的类型,例如int?.
但是,我从数据库中读取了一个可以为空的int列,如下所示:
MyProperty = reader.GetValueOrDefault<int?>("SomeColumnName")
调试模式显示val是-1并且T是int ?,但是我得到InvalidCastException.从this post开始,我认为这是因为拆箱和铸造不能在一次操作中执行(val是具有短值的对象类型),但是我能做些什么来使它在我的情况下工作?由于它是一种通用方法,我不知道在进行转换之前如何手动取消它.
解决方法:
要获得非常好的答案,您需要发布a good, minimal, complete code example.
如果转换为int失败,则盒装值不是int.您应该能够在调试器中看到它实际上是什么.
也就是说,Convert类在转换方面要复杂得多;演员表需要完全匹配,即盒装值必须是int(文字-1将是一个int,但在你的情况下,值来自who-know-where,很容易可能是short或long或者其他) .
所以不是演员,而是一个电话,例如转换为.ToInt32()会更好.
在您的情况下,使用泛型方法(即在编译时类型未知),Convert.ChangeType()方法可能更合适:
public static T GetValueOrDefault<T>(this SqlDataReader reader, string columnName, T defaultValue = default(T))
{
object val = reader[columnName];
if (val == null || val == DBNull.Value)
{
return defaultValue;
}
return (T)Convert.ChangeType(val, typeof(T));
}
标签:c,casting,unboxing,generics 来源: https://codeday.me/bug/20190609/1205061.html