什么是与.NET.NET的CType函数等效的C#用于泛型类型?

时间:2014-10-01 14:35:55

标签: c# vb.net generics casting type-conversion

假设我在名为MyTable的SQL Server数据库中有一个名为MyDB的表,其中包含以下三个记录:

|ID|MyVarcharColumn|
--------------------
|1|123|
|2|2014-10-01 9:58 AM|
|3|True|

现在假设我有以下VB.NET代码:

Public Shared Sub Test()
    Dim myIntValue As Integer = GetValue(Of Integer)(1)
    Dim myDateValue As Date = GetValue(Of Date)(2)
    Dim myBooleanValue As Boolean = GetValue(Of Boolean)(3)
End Sub

Public Shared Function GetValue(Of T)(ByVal id As Integer) As T
    Dim ds As System.Data.DataSet = GetSQLDataSet(String.Format("SELECT MyVarcharColumn FROM MyTable WHERE ID={0}", id))
    Return CType(ds.Tables(0).Rows(0).Item("MyVarcharColumn"), T)
End Function

Public Shared Function GetSQLDataSet(ByVal ForQuery As String) As DataSet
    GetSQLDataSet = New DataSet()
    Dim conn As New System.Data.SqlClient.SqlConnection("Data Source=MyDBServer;Initial Catalog=MyDB;Integrated Security=True")
    Dim cmd As New System.Data.SqlClient.SqlCommand(ForQuery, conn)
    conn.Open()
    Dim da As New System.Data.SqlClient.SqlDataAdapter(cmd)
    da.Fill(GetSQLDataSet)
    conn.Close()
End Function

我可以致电Test(),一切正常。值得注意的是,使用VB.NET的CType函数以某种方式在转换(而不是 cast )中成功,因为底层数据库列值是一个字符串)进入正确的类型。

现在,如果我相信Correct C# conversion counterpart for VB's CTYPE()How do I translate VB.Net's CType() to C#之类的内容,我应该可以使用以下C#代码:

static void Main(string[] args)
{
    int myIntValue = GetValue<int>(1);
    DateTime myDateValue = GetValue<DateTime>(2);
    bool myBooleanValue = GetValue<bool>(3);
}

static T GetValue<T>(int id)
{
    System.Data.DataSet ds = GetSQLDataSet(String.Format("SELECT MyVarcharColumn FROM MyTable WHERE ID={0}", id));
    return (T)ds.Tables[0].Rows[0]["MyVarcharColumn"];
}

public static System.Data.DataSet GetSQLDataSet(string forQuery)
{
    System.Data.DataSet ret = new System.Data.DataSet();
    System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection("Data Source=MyDBServer;Initial Catalog=MyDB;Integrated Security=True");
    System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(forQuery, conn);
    System.Data.SqlClient.SqlDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(cmd);
    conn.Open();
    da.Fill(ret);
    conn.Close();
    return ret;
}

但是,我在运行时遇到错误return (T)ds.Tables[0].Rows[0]["MyVarcharColumn"];说&#34;指定演员表无效&#34;。

我知道我没有投出,因为返回类型是一个字符串,所以我真正需要的是转换。在VB.NET中,CType函数既有角色,也有角色。但是,在C#中,似乎我使用了Convert.ToInt32()之类的显式类型转换函数。由于我在这里处理泛型类型,因此无效。

我想如果我可以把它归结为一个问题,那就是:在C#中,如何将字符串转换为像VB.NET CType这样的泛型类型?

1 个答案:

答案 0 :(得分:1)

如果需要支持其支持的一组非常具体的类型,那么Convert.ChangeType可能没问题:

object value = (string) ds.Tables[0].Rows[0]["MyVarcharColumn"];
return (T) Convert.ChangeType(value, typeof(T));

您可能还需要考虑指定格式提供程序。我会强烈鼓励你避免这种代码。例如,您对double值的期望是什么?那么DateTime呢?理想情况下,您可以将这些存储在SQL中的不同列中,这样您就可以避免自己进行任何转换 - 但如果您必须使用字符串,我可能会非常明确地使用它。格式化和解析,例如使用ISO-8601格式表示DateTime值。你目前的做法使文化问题变得非常脆弱。

我还强烈建议您停止动态构建SQL。即使是整数也不理想,因为你没有指定格式提供者,但在所有案例中使用参数化SQL只是一个很好的习惯。