取消装箱 -1 并使用泛型转换为 Nullable<int> 会产生 InvalidCastException
Unboxing -1 and casting to Nullable<int> using generics yields InvalidCastException
在 this SO post 中,我找到了一个通用扩展方法,如果 SqlDataReader
读取的值是 null
或 DBNull.Value
,则该方法 returns 是默认值,否则正确转换的值。我是这样实现的:
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;
}
上面链接的 post 中的方法下面提到的示例没有使用正确的语法,但仍然建议这也适用于可空类型,例如 int?
.
但是,我从数据库中读取了一个可为空的 int
列,如下所示:
MyProperty = reader.GetValueOrDefault<int?>("SomeColumnName")
调试模式显示 val
是 -1
,T
是 int?
,但我得到了 InvalidCastException。从 this post 我认为这是因为不能在单个操作中执行拆箱和转换(val
是类型 object
持有 short
值),但我能做什么使它在我的情况下起作用?由于它是一种通用方法,我不知道如何在进行转换之前将其手动拆箱。
要获得真正好的答案,您需要 post a good, minimal, complete code example。
如果转换为 int
失败,则装箱值不是 int
。您应该能够在调试器中看到它实际上是什么。
也就是说,Convert
class 在转换方面要复杂得多;转换将需要 精确 匹配,即盒装值必须是 int
(文字 -1
将是 int
,但在您的如果值来自谁知道哪里,很容易是 short
或 long
或其他任何东西)。
所以不是演员,而是一个电话,例如Convert.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));
}
在 this SO post 中,我找到了一个通用扩展方法,如果 SqlDataReader
读取的值是 null
或 DBNull.Value
,则该方法 returns 是默认值,否则正确转换的值。我是这样实现的:
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;
}
上面链接的 post 中的方法下面提到的示例没有使用正确的语法,但仍然建议这也适用于可空类型,例如 int?
.
但是,我从数据库中读取了一个可为空的 int
列,如下所示:
MyProperty = reader.GetValueOrDefault<int?>("SomeColumnName")
调试模式显示 val
是 -1
,T
是 int?
,但我得到了 InvalidCastException。从 this post 我认为这是因为不能在单个操作中执行拆箱和转换(val
是类型 object
持有 short
值),但我能做什么使它在我的情况下起作用?由于它是一种通用方法,我不知道如何在进行转换之前将其手动拆箱。
要获得真正好的答案,您需要 post a good, minimal, complete code example。
如果转换为 int
失败,则装箱值不是 int
。您应该能够在调试器中看到它实际上是什么。
也就是说,Convert
class 在转换方面要复杂得多;转换将需要 精确 匹配,即盒装值必须是 int
(文字 -1
将是 int
,但在您的如果值来自谁知道哪里,很容易是 short
或 long
或其他任何东西)。
所以不是演员,而是一个电话,例如Convert.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));
}