C# DataTable将字段值转换为T

C# DataTable将字段值转换为T,c#,.net,generics,casting,C#,.net,Generics,Casting,我有以下功能: public T GetScalar<T>(string sql, T defaultValue, SQLParam[] sqlParams = null) { DataTable dt = GetDataTable(sql, sqlParams); if (dt.Rows.Count == 0) return defaultValue; else { try { object t

我有以下功能:

public T GetScalar<T>(string sql, T defaultValue, SQLParam[] sqlParams = null)
{
    DataTable dt = GetDataTable(sql, sqlParams);
    if (dt.Rows.Count == 0) return defaultValue;
    else
    {
        try
        {
            object tmp = dt.Rows[0][0];
            return (T)tmp;
        }
        catch { return defaultValue; }
    }
}
public T GetScalar(字符串sql,T defaultValue,SQLParam[]sqlParams=null)
{
DataTable dt=GetDataTable(sql,sqlParams);
如果(dt.Rows.Count==0)返回defaultValue;
其他的
{
尝试
{
对象tmp=dt.行[0][0];
返回(T)tmp;
}
catch{return defaultValue;}
}
}
我收到一个
无效的异常

在调试期间,我可以看到
tmp
的值是3,
T
的类型是
int

这里有什么问题

编辑

一点背景知识:这在MySQL中是可以使用的。我现在已经转移到SQLServer(谢天谢地,这段代码没费多大力气),但现在失败了。

我怀疑该值实际上是一个
长的
,或者类似的值-当您取消装箱时,您必须取消装箱到确切的类型(签名和枚举有一些奇怪之处,但不是
长的
int

如果您在
tmp.GetType()
上放置一个手表,或者只是从SQL中计算出它应该是什么类型,您应该能够看到这一点。

我怀疑该值实际上是一个
长的
,或者类似的东西-当您取消X时,您必须取消X到确切的类型(关于符号和枚举有一些奇怪之处,但不是
long
vs
int


如果您将手表放在
tmp.GetType()
上,或者只是从SQL中计算出它应该是什么类型,您应该能够看到这一点。

尝试更改行:

return (T)tmp;


尝试更改您的线路:

return (T)tmp;


尝试将
Try
块中的代码更改为:

        T tmp = dt.Rows[0].Field<T>(0);
        return tmp;
T tmp=dt.行[0]。字段(0);
返回tmp;

看看这是否有效-或者至少会给您带来更好的错误。:-

尝试将
Try
块中的代码更改为:

        T tmp = dt.Rows[0].Field<T>(0);
        return tmp;
T tmp=dt.行[0]。字段(0);
返回tmp;


看看这是否有效——或者至少会给你一个更好的错误。:-)

为什么首先要声明对象?为什么不只是
T tmp
?如果您只想要一个标量,那么首先为什么要加载到
DataTable
?(这纯粹是出于好奇)@Joel-我把tmp放在那里只是为了调试,最初它是
return(T)dt.Rows[0][0]
也许你也想用这个方法访问datarow。奇怪的是-这在MySQL中工作(使用完全相同的代码)-但现在我需要转移到SQLServer,因为其他原因。这段代码现在中断了。为什么首先要声明对象?为什么不只是
T tmp
?如果您只想要一个标量,那么首先为什么要加载到
DataTable
?(这纯粹是出于好奇)@Joel-我把tmp放在那里只是为了调试,最初它是
return(T)dt.Rows[0][0]
也许你也想用这个方法访问datarow。奇怪的是-这在MySQL中工作(使用完全相同的代码)-但现在我需要转移到SQLServer,因为其他原因。这段代码现在坏了。@MarcGravel:Sleep at the wheel:(手表刚刚显示它的类型是
object{int}
。数据库类型也是int。我不明白为什么它不工作,但Michal的解决方案适用于now@Simon:你真的调用了
GetType()吗
但是?如果你真的有一个int并且不能转换成它,那将是非常奇怪的…这就是我得到的:
类型t2=tmp.GetType()
=
t2{Name=“Int32”,FullName=“System.Int32”}
@Simon:和
类型(t)
?你能拿出一个简短但完整的程序来演示这一点吗?我发现很难相信你成功地打破了拆箱…@MarcGravel:在方向盘上睡着了:(手表刚刚显示它是
object{int}类型的。)
。数据库类型也是int。不明白为什么它不工作,但Michal的解决方案适用于now@Simon:你真的调用了
GetType()
吗?如果你真的有一个int并且不能转换成它,那将是非常奇怪的…这就是我得到的:
Type t2=tmp.GetType()
=
t2{Name=“Int32”,FullName=“System.Int32”}
@Simon:和
typeof(T)
?你能制作一个简短但完整的程序来演示这一点吗?我很难相信你成功地打破了拆箱。。。