将List <object>强制转换为List <string>

时间:2018-07-29 20:56:22

标签: c# generics casting

我已经花了很多时间尝试解决这个问题,但我不明白为什么我不能这么做。我正在执行查询,并从特定列中提取所有值,然后将其存储在List中,因为它可能是int,字符串或bool。问题是在投射期间,我想要一个动态解决方案,可以验证对象类型并进行相应投射。

//This handles the db connection and makes calls DbItems class
    public List<object> GetDBColumns(string sqlQuery, string column)
            {
                using (SqlConnection connection = new SqlConnection(connectionString))
                {
                    connection.Open();
                    var reader = new SqlCommand(sqlQuery, connection).ExecuteReader();
                    var values = DbItems.GetColumns(reader, column);
                    connection.Close();
                    return values;
                }
            }

Public class DbItems
{

 DbItems(SqlDataReader reader, string column)
    {   //GetInt32 won't be able to handle other types of course, what could I use?
        columnData.Add(reader.GetInt32(reader.GetOrdinal(column)));
    }

    List<object> columnData = new List<object>();

    //I'm calling this static method that invokes the constructor 
    public static List<object> GetColumns(SqlDataReader reader, string column)
        {
            List<object> dataSet = new List<object>();
            while (reader.Read())
            {
                dataSet.Add(new DbItem(reader, column).columnData);
            }
            return dataSet;
        }
    }

这没有问题,但是随后我得到一个要转换为字符串的int值,并使用了Cast <>,(string)columnData [0]和其他一些在线建议,没有任何效果。请协助。

2 个答案:

答案 0 :(得分:1)

List<object>投射到List<string>将需要List的通用参数T中的contravariance。不幸的是,List<T>不符合互变标准,因为它不是 interface delegate array 类型,并且因为它是通用参数相反变量将不是类型安全的(例如,这样做将允许List<string>不仅包含字符串,还包含任何其他对象,这显然是不存在的,不是类型安全的,因此是不允许的)。出于这个原因,您不能将List<object>投射到List<string>

但是,您可以创建一个新的List<string>并复制原始List<object>中的所有项目,同时将每个项目转换为字符串。使用Cast<>(string)columnData[0]进行项目转换在这里不起作用(除非项目实际上是string s),因为将 reference-type 对象强制转换为另一个引用类型仅执行分配兼容性检查,而不执行对象的任何转换

幸运的是,转换为string很简单,因为所有对象都从.ToString()类型继承了Object方法。因此,您可以使用以下内容转换为List<string>

List<string> stringList = columnData.ConvertAll(item => item?.ToString());

但是,当然,如果.ToString()不满足您的需要,您可以使用任何其他转换,例如使用Convert类在原始类型之间进行转换。

答案 1 :(得分:0)

最简单的方法是调用ToString方法,因为所有对象都有一个ToString方法

var values = columnData.Select(x => x?.ToString()).ToList();