jbenscoter
jbenscoter

Reputation: 181

Getting an ArrayTypeMismatchException with an array of objects

I am writing a very simple method to convert a csv to a datatable so it can be inserted into a SQL database. It works exactly how it should, unless I try to replace empty strings with DBNull.Value, then it throws an ArrayTypeMismatchException. The stream coming in is a simple comma-separated file with the data.

The problem code:

public static DataTable StreamToTable(Stream stream, bool headersAvailable, bool convertBlankToDBNull)
    {

        DataTable data = new DataTable();
        StreamReader reader = new StreamReader(stream);

        if (!reader.EndOfStream)
        {
            if (headersAvailable)
            {
                try
                {
                    //get headers from first line
                    string[] headers = reader.ReadLine().Split(',');

                    //construct headers
                    for (int i = 0; i < headers.Length; i++)
                    {
                        data.Columns.Add(headers[i]);
                    }
                }
                catch (IOException ioEx)
                {
                    return null;
                }
            }

            while (!reader.EndOfStream)
            {
                object[] row = reader.ReadLine().Split(',');

                if (convertBlankToDBNull)
                {
                    for (int i = 0; i < row.Length; i++)
                    {
                        if (row[i].ToString().Equals(""))
                        {
                            row[i] = DBNull.Value; //this is where I get the exception
                        }
                    }
                }
                data.Rows.Add(row);
            }

            return data;
        }
        else return null;
    }

I can't figure out what I am doing wrong... I should be able to assign anything to the array because it's an object array, so how can there be a type mismatch?

Upvotes: 2

Views: 1175

Answers (1)

SLaks
SLaks

Reputation: 887807

You've discovered the horrors of unsafe array covariance.

row is a string[] that has been unsafely cast to object[]. Even though that cast succeeds, the array is still a string[] (since that's what Split() returns), and cannot be used as an object[].
In particular, it still can't hold things that aren't strings.

Instead, you can create a new object[] and populate it with those strings:

object[] row = Array.ConvertAll(
    reader.ReadLine().Split(','),
    s => (object)s
);

Upvotes: 3

Related Questions