简体   繁体   中英

Multidimensional Array Casting Runtime Error ---> unable to cast object of type 'System.Object[,]' to type 'System.String

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM