为什么var推断类型对象而不是XmlNodeList循环中的XmlNode?

如果像这样循环遍历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有帮助吗?

XmlNodeList只实现非通用的IEnumerable接口,而不是像带有generics的IEnumerable 。 这样可以防止强大地键入其元素,直到您进行适当的转换,因此编译器别无选择,只能将隐式类型声明映射到foreach中的object

如果你坚持使用var关键字,你可以像这样xmlNodeList的元素:

 foreach (var foo in xmlNodeList.Cast()) { string baa = foo.Attributes["baa"].Value; } 

但这很难看,无论如何都需要更多的按键操作。 您也可以只是显式声明XmlNode foo ,并让foreach随时为您投射它。

正如BoltClock所说, XmlNodeList只实现了IEnumerable

foreach循环会在幕后自动为您进行投射,因此:

 List values = new List { "x", "y", "z" }; foreach (string x in values) { ... } 

是完全合法的,并且对每个值执行强制转换(当然可以抛出exception)。

我的第二个问题你的意思并不是很清楚 – 但我只是建议你在循环中明确使用XmlNode 。 如果你真的想使用var ,你可以写:

 foreach (var foo in xmlNodeList.Cast()) 

但这对我来说太过分了……

在支持generics之前, XmlNodeList已经在.NET Framework中。 因此,它只实现非通用接口IEnumerable而不是通用IEnumerable
要了解此列表中可以包含哪些类型,您需要阅读文档。 最好的方法是索引器 。

BTW:自从Visual Studio 2005发布以来,IDE还没有被称为VS.NET :-)从那时起它就被称为VS.