C# 从SqlString转换为String,从SqlBoolean转换为bool,等等

C# 从SqlString转换为String,从SqlBoolean转换为bool,等等,c#,casting,sql-types,C#,Casting,Sql Types,我有一个可以从C中的记录集转换过来的工作代码,但我也遇到了其他方法,我一直在研究它们的用途。以下是测试代码: `using (DataTableReader reader = new DataTableReader(ds2.Tables[0])) { while (reader.Read()) { //sample of working code. The values are on the far right. string val1 = re

我有一个可以从C中的记录集转换过来的工作代码,但我也遇到了其他方法,我一直在研究它们的用途。以下是测试代码:

`using (DataTableReader reader = new DataTableReader(ds2.Tables[0]))
 {
    while (reader.Read())
    {       

    //sample of working code. The values are on the far right.
    string val1 = reader[0] is DBNull ? default(string) : reader[0].ToString(); //value = "test"
    int val2 = reader[2] is DBNull ? default(int) : Convert.ToInt32(reader[2].ToString());  //value = 23
    bool val3 = reader[26] is DBNull ? default(bool) : reader[26].ToString() == "1" ? true : false;     //value = true
    DateTime val4 = reader[16] is DBNull ? default(DateTime) : Convert.ToDateTime(reader[16].ToString());  //value=  10/6/2013 6:31:33 AM

    //the first approach
    string val5 = reader[0] as string;
    int? val6 = reader[2] as int? ?? default(int);
    bool? val7 = reader[26] as bool? ?? default(bool);
    DateTime? val8 = reader[16] as DateTime? ?? default(DateTime);

    //the second approach
    string val9 = reader[0] is DBNull ? default(string) : reader.GetString(0);
    int val10 = reader[2] is DBNull ? default(int) : reader.GetInt32(2); ;
    bool val11 = reader[26] is DBNull ? default(bool) : reader.GetBoolean(26);
    DateTime val12 = reader[16] is DBNull ? default(DateTime) : reader.GetDateTime(16);

    //the third approach
    var val13 = reader[0] is DBNull ? default(string) : (string)reader[0];
    int val14 = reader[2] is DBNull ? default(int) : (int)reader[2]; ;
    bool val15 = reader[26] is DBNull ? default(bool) : (bool)reader[26];
    DateTime val16 = reader[16] is DBNull ? default(DateTime) : (DateTime)reader[16];

    //the 4th approach                
    int val17 = reader[2] is DBNull ? default(int) : (int) Int32.Parse(reader[2].ToString());
    bool val18 = reader[26] is DBNull ? default(bool) : (bool) Boolean.Parse( reader[26].ToString()=="1"? "true" : "false");
    DateTime val19 = reader[16] is DBNull ? default(DateTime) : (DateTime) DateTime.Parse(reader[16].ToString());

    }
}`
显示了第一种和第二种方法的示例。我采用的第三种方法。第四种方法是从

在第一种方法中,as运算符与??运算符的默认值,因为as运算符处理强制转换并检查DBNull,注释者注意到,如果出现错误,这将自动失败。使用这段代码,我将得到字符串的null值和其余字符串的默认值,这表明“as”操作符不知何故失败了

第二种方法使用读者的Getxxxx方法。但这会引发异常,无法将类型为“System.Data.SqlTypes.SqlString”的对象强制转换为类型为“System.String”。对于字符串和指定的强制转换无效。为了其他人。第三种方法使用强制转换并生成与第二种方法相同的异常

第四种方法可以工作,首先将数据转换为字符串,解析字符串,最后转换为预期的类型。我在使用TryParse和Convert.ChangeType时还遇到了一些,但它们更详细

我的问题是,那些其他的方法似乎对其他人有效——它们是答案,而且是上等票——但为什么我在使用它们的时候不行呢?我做错了什么?如果这些方法能够发挥作用,那么哪种方法是最有效的

编辑: 正如@usr所建议的,我应该使用一些helper方法。以下是我将用于工作代码的helper方法,以及示例用法:

    public static T GetColumnValue<T>(this DataTableReader reader, string columnName)
    {
        T result = default(T);
        int index = reader.GetOrdinal(columnName);

        if (!reader.IsDBNull(index))
        {                                
            result = (T)Convert.ChangeType(reader[index].ToString(), typeof(T));                                
        }

        return result;         
    }

    //used as 
    string val1 = reader.GetColumnValue<string>("Column1"); 
    int val2 = reader.GetColumnValue<int>("Column2"); 
    bool val3 = reader.GetColumnValue<bool>("Column3"); 
    DateTime val4 = reader.GetColumnValue<DateTime>("Column4"); 

当然,这对其他方法不起作用。我仍然很好奇为什么其他方法不起作用。谢谢。

这个问题似乎离题了,因为它属于我,即使我的问题是他们为什么不处理我的代码?使用reader.IsDBNull0?defaultstring:reader.GetString0。您的代码是高度冗余的。一些辅助方法会产生奇迹。@Tim,我会的,谢谢。