使用对象数组获取ArrayTypeMismatchException

时间:2012-11-27 21:57:31

标签: c# .net exception

我正在编写一个非常简单的方法,将csv转换为数据表,以便将其插入到SQL数据库中。除了我尝试用DBNull.Value替换空字符串之外,它确实应该如何工作,然后它抛出一个ArrayTypeMismatchException。进来的流是一个带有数据的简单逗号分隔文件。

问题代码:

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;
    }

我无法弄清楚我做错了什么......我应该能够为数组分配任何东西,因为它是一个对象数组,那么怎么会出现类型不匹配?

1 个答案:

答案 0 :(得分:2)

你发现了unsafe array covariance的恐怖。

rowstring[],已被不安全地投射到object[]。即使该转换成功,该数组仍然是string[](因为这是Split()返回的内容),并且不能使用作为object[]
特别是,它仍然无法容纳不是string的东西。

相反,您可以创建一个新的object[]并使用string s填充它:

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