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

本文关键字:对象 类型 XmlNode var XmlNodeList 循环 为什么 | 更新日期: 2023-09-27 18:22:16

如果像这样循环访问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 是对象类型。类型推断有点工作,但推断对象

显然,XmlNodeList 的元素不是一个定义的类型,但是将它们分配给 XmlNode 而不是 var 会隐式地执行某些操作(强制转换或取消装箱(。

第一个问题:这背后的机制是什么?

第二个(相关(问题:如何找到可以在这种循环中使用的类型?VS.NET IDE 是否有帮助?

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

>XmlNodeList只实现了非泛型IEnumerable接口,而不是像泛型IEnumerable<XmlNode>那样的东西。这样可以防止在适当转换之前强类型化其元素,因此编译器别无选择,只能将隐式类型声明映射到 foreach 中的object

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

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

但这很丑陋,无论如何需要更多的击键。你不妨直接声明XmlNode foo,让foreach在飞行中为你投射它。

正如 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>())

但这对我来说有点矫枉过正...

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

顺便说一句:自从Visual Studio 2005发布以来,IDE就没有被调用过 VS.NET:-(从那时起,它才被称为VS。