C#中foreach循环用var替代XmlNode报错问题咨询
问题:XmlNodeList遍历中使用var报错的原因分析
正常运行的代码
using System; using System.Threading.Tasks; using System.Xml; namespace cabinet; public class Program { public static void Main(string[] args) { XmlNodeList nodeList = XMLUtils.GetXPathNodes("./data/xml/cabinet.xml", "//cab:numéro"); foreach (XmlNode node in nodeList) { Console.WriteLine(node.InnerText); } } }
修改后报错的代码片段
foreach (var node in nodeList) { Console.WriteLine(node.InnerText); }
错误信息
'object' does not contain a definition for 'InnerText' and no accessible extension method 'InnerText' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
用户疑问
我推测编译器无法推断node的类型,将其视为object,但我认为基于多态,即使是object类型也应该能正常工作,这一观点是否正确?请解释为何此处使用var会失效。
解答
你的观点不正确,多态在这里不适用,原因如下:
XmlNodeList的集合类型限制:XmlNodeList实现的是非泛型IEnumerable接口,这个接口的枚举器返回的
Current属性类型是object。所以用var声明循环变量时,编译器会直接把node推断为object类型。多态不支持编译时无定义的成员调用:多态的核心是运行时调用实际类型的方法,但前提是编译时必须能从变量的静态类型(编译器看到的类型)找到对应的成员。
object类型本身没有InnerText属性,所以编译器在编译阶段就会报错,不会等到运行时再去判断实际类型。显式指定类型的作用:当你写
foreach (XmlNode node in nodeList)时,编译器会自动插入显式类型转换——每次循环都会把枚举器返回的object实例强制转成XmlNode(转换失败会抛InvalidCastException)。此时node的静态类型是XmlNode,编译器能识别到InnerText属性,自然可以正常编译运行。
总结来说:非泛型集合的遍历中,var会被推断为object,而object没有你要调用的InnerText属性;显式指定XmlNode类型则会完成类型转换,让编译时能识别到目标成员。
内容的提问来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

