I am having trouble with what should be a simple cast of a multidimensional object array ( object[,]
) to a new data type ( string[,]
) for logging purposes. The format is a dynamic two dimensional array that has many columns and rows, but doesn't fit nicely into one of the generic collection objects offered in the framework. I would just strong type it as a string[,]
all the way through the process, but I need the flexibility of the object array, because in some instances I will need to use different data types.
private List<KeyValuePair<string, object>> _dataList = new List<KeyValuePair<string, object>>();
private object[,] _dataArray;
public List<KeyValuePair<string, object>> RetrieveHistoricalData()
{
...
//Calling Method (for explaination and context purposes)
_log.Log ("\r\nRetrieveHistoricalData", "_dataList.Count: " + _dataList.Count);
_dataList.ForEach(dli => _log.Log ("\r\nRetrieveHistoricalData", "_dataList: "
+ dli.Key + ((object[,])dli.Value)
.CastTwoDimensionalArray<string>()
.TwoDimensionalArrayToString()));
...
}
... Added An Extension method based on Jon Skeet's suggestions ...
internal static T[,] CastTwoDimensionalArray<T>(this object[,] dataArray)
{
int rows = dataArray.GetLength(0);
int columns = dataArray.GetLength(1);
T[,] returnDataArray = new T[rows, columns];
for (int row = 0; row < rows; row++)
{
for (int column = 0; column < columns; column++)
{
returnDataArray[row, column] =
(T)Convert.ChangeType(dataArray[row, column], typeof(T));
}
}
return returnDataArray;
}
... Here's my own addition (only included because it is in the line I am executing) ...
internal static string TwoDimensionalArrayToString<T>(this T[,] dataArray)
{
int rows = dataArray.GetLength(0);
int columns = dataArray.GetLength(1);
string returnString = "";
for (int row = 0; row < rows; row++)
{
for (int column = 0; column < columns; column++)
{
returnString = returnString + "[" + row + "," + column + "] =>" + dataArray[row,column]+ " ; ";
}
}
return returnString;
}
I have edited the code above from the first post, but I am still receiving a System.InvalidCastException when trying to convert a System.Double to a System.String in the Generic extension method. I am working on a simple way to add some exceptions through type reflection to remove the remaining issue.
Thanks.
EDIT: You can only cast from object[,]
to string[,]
if the array involved really is a string[,]
originally. For example, this is fine:
object[,] o = new string[,]
{
{ "x", "y" },
{ "a", "b" }
};
string[,] x = (string[,]) o;
... but this isn't:
object[,] o = new object[,]
{
{ "x", "y" },
{ "a", "b" }
};
string[,] x = (string[,]) o; // Bang!
Even though each element of the array is a string, it still isn't a string array. In the latter case, you'll need to write your own code to create a new array object and perform the element-wise conversion. For example, here's a generic method you can use to cast each element:
using System;
class Test
{
static void Main()
{
object[,] o = new object[,]
{
{ "x", "y" },
{ "a", "b" }
};
string[,] x = Cast2D<string>(o);
Console.WriteLine(x[1, 1]); // "b"
}
static T[,] Cast2D<T>(object[,] input)
{
int rows = input.GetLength(0);
int columns = input.GetLength(1);
T[,] ret = new T[rows, columns];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
ret[i, j] = (T) input[i, j];
}
}
return ret;
}
}
In your case you'd probably want:
object[,] array = (object[,]) financialDataObject;
string[,] financialData = Cast2D<string>(array);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.