指定具体类型而不是var

时间:2013-08-08 22:13:02

标签: c# asp.net

我有以下代码,它给出了错误cannot apply indexing with [] to an expression of type object

protected void btnMakeCards_Click(object sender, EventArgs e)
{
    string cs = ConfigurationManager.ConnectionStrings["dbcs"].ConnectionString;
    using (var con = new SqlConnection(cs))
    using (var cmd = new SqlCommand("spDrugCardGenerator", con))
    {
        con.Open();
        cmd.CommandType = CommandType.StoredProcedure;
        DataTable dt = new DataTable();
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        da.Fill(dt);

        foreach (var row in dt.Rows)
        {
            foreach (var col in dt.Columns)
            {
                Response.Write(row[col].ToString());
            }
        }
    }
}

如果我使用DataRowDataColumn的具体类型,为什么这段代码编译得很好?编译器可以推断出using语句中的数据类型。数据表的处理是什么?

3 个答案:

答案 0 :(得分:4)

因为DataTable.Rows返回DataRowCollectionDataRowCollection的{​​{1}}方法仅返回GetEnumerator,而不是通用IEnumerable。因此,推断出的类型是IEnumerable<T>

显然,您无法在object上调用索引器方法。

编辑:

正如user7116所评论的那样,object只会“接受”您想要的任何内容。然而,使用实际类型会产生底层强制转换。这是生成的IL:

var

这导致预期的行为。

答案 1 :(得分:2)

DataTable的行和列集合是IEnumerable但不是IEnumerable <T>,因此它们确实返回object,因为它们不是通用的。

您可以使用DataTable.AsEnumerable扩展方法(http://msdn.microsoft.com/en-us/library/system.data.datatableextensions.asenumerable.aspx)来处理前者。

答案 2 :(得分:1)

问题在于,dt.RowsDataRowCollection,实现IEnumerable,而不是IEnumerable<DataRow>。这意味着当您执行foreach (var row in dt.Rows)时,var只能解析为object。以下是两个选项,每个选项只是将对象转换为适当的数据类型:

foreach (DataRow row in dt.Rows)
{
    foreach (DataColumn col in dt.Columns)
    {
        Response.Write(row[col].ToString());
    }
}
// or
foreach (var row in dt.Rows.Cast<DataRow>())
{
    foreach (var col in dt.Columns.Cast<DataColumn>())
    {
        Response.Write(row[col].ToString());
    }
}

如果确实想要使用隐式类型的var,则必须采用类似这样的方式,我推荐。

for (var i = 0; i < dt.Rows.Count; i++)
{
    var row = dt.Rows[i];
    for (var j = 0; j < dt.Columns.Count; j++)
    {
        var col = dt.Columns[j];
        Response.Write(row[col].ToString());
    }
}

(这是有效的,因为DataRowCollection的{​​{3}}是强类型的)