如果有人像这样循环遍历XmlNodeList
foreach (XmlNode foo in xmlNodeList) {string baa = foo.Attributes["baa"].Value;}
一切都按预期工作 - foo显然是 XmlNode 类型,VS.NET IDE显示方法和字段。
另一方面
foreach (var foo in xmlNodeList) { string baa = foo.Attributes["baa"].Value; }
没有编译,因为这里的foo是 object 类型。键入推断类型的工作,但推断对象。
显然,XmlNodeList的元素不是一个定义的类型,但是将它们分配给XmlNode而不是var会隐式地执行某些操作(强制转换或取消装箱)。
第一个问题:背后的机制是什么?
第二个(相关)问题:如何找到可以在这种循环中使用的类型? VS.NET IDE有帮助吗?
答案 0 :(得分:9)
XmlNodeList
仅实现非通用IEnumerable
接口,而不是IEnumerable<XmlNode>
类似于泛型的接口。这样可以防止对元素进行强类型操作,直到您进行适当的转换,因此编译器别无选择,只能将隐式类型声明映射到foreach中的object
。
如果您坚持使用var
关键字,则可以像这样投射xmlNodeList
的元素:
foreach (var foo in xmlNodeList.Cast<XmlNode>())
{
string baa = foo.Attributes["baa"].Value;
}
但这很难看,无论如何都需要更多的击键。您也可以明确声明XmlNode foo
,并让foreach随时为您投射。
答案 1 :(得分:4)
正如BoltClock所说,XmlNodeList
只实现IEnumerable
。
foreach
循环会在幕后自动为您投射,所以:
List<object> values = new List<object> { "x", "y", "z" };
foreach (string x in values)
{
...
}
完全合法,并且对每个值执行强制转换(当然可以抛出异常)。
我不清楚你的第二个问题是什么意思 - 但我建议你在循环中明确使用XmlNode
。如果确实想要使用var
,您可以写:
foreach (var foo in xmlNodeList.Cast<XmlNode>())
但这对我来说太过分了......
答案 2 :(得分:4)
XmlNodeList已经在.NET Framework中。因此,它仅实现非通用接口IEnumerable
而不是通用IEnumerable<T>
要了解此列表中可以包含哪些类型,您需要阅读文档。最好的方法是indexer。