Reputation: 81
I've spent way to much time on trying to resolve this and I don't understand why I can't cast this. I'm executing a query and pulling all the values from a specific column that is then stored in a List since it could be an int, string, or bool. The issue is during casting, I would like a dynamic solution that can validate the object type and cast accordingly.
//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;
}
}
This works without issue, but then I'll get an int value that I'd like to cast a string and I've used Cast<>, (string)columnData[0], and a couple other suggestions online and nothing works. Please assist.
Upvotes: 0
Views: 2781
Reputation: 20987
The easiest way to do so would be just call the ToString
Method, since all object have a ToString
Method
var values = columnData.Select(x => x?.ToString()).ToList();
Upvotes: 0
Reputation: 6207
Casting List<object>
to List<string>
would require contravariance of List
's generic parameter T
. Unfortunatelly List<T>
does not meet criteria for contravariance, because it is not an interface, delegate or array type, and because making it's generic parameter contravariant wouldn't be type-safe (doing so would e.g. allowed List<string>
to contain not only strings, but any other object, which is obviously nonsence, not type-safe and therefore not allowed). Fot this reason, you cannot cast List<object>
to List<string>
.
What you can, however, is to create new List<string>
and copy there all items from original List<object>
, while converting each item to string. Item conversion with Cast<>
or (string)columnData[0]
will not work here (unless items are actually a string
s), because casting a reference-type object to another reference-type only performs assignment compatibility check, but does not perform any conversion of the object.
Luckily, converting to string
is trivial, since all objects inherits .ToString()
method from Object
type. So you can convert to List<string>
with the following:
List<string> stringList = columnData.ConvertAll(item => item?.ToString());
But of course, you can use any other conversion, if .ToString()
does not meet your needs, such as using Convert class to perform conversion between primitive types.
Upvotes: 1