让cls
类型XmlNode
以下语句允许我访问子节点:
foreach (XmlNode child in cls.ChildNodes)
现在,当我尝试使用 var 时:
foreach (var child in cls.ChildNodes)
那么孩子的类型不是XmlNode
,只有对象。我不能使用child.NodeType
,编译器说:
object'不包含'NodeType'的定义
为什么是这样?
ChildNodes
XmlNodeList
是定义为的类型
public abstract class XmlNodeList : IEnumerable, IDisposable
它的枚举器返回一个object
. 当您使用XmlNode
代替时var
,.net 会自动casts
反对XmlNode
. 但是当你使用时var
,child 被视为一个对象。
正如我最近自己发现的那样,foreach 循环对元素变量的类型进行了显式转换。这来自于引入泛型的 C# 2.0 之前的时间。
List myList = getStringList();
foreach (string element in myList)
{
// ...
}
即使myList
只是一个List
,不是通用的,因此只包含对象,我知道它包含字符串,并且可以执行这个 foreach 循环,这将为我添加显式转换。
输入泛型。突然间你不再需要它了,但它仍然是语言的一部分。
List<string> myList = getStringList();
foreach (string element in myList)
{
// ...
}
然而,这现在可能有可怕的陷阱:
List<long> myLongList = getLongList();
foreach (int element in myLongList)
{
// ...
}
这不会产生错误、警告、运行时异常。即使我在没有检查的情况下将多头转换为整数。我很有可能刚刚损坏了我的数据。哎哟。如何避免这种情况?
通过使用var
, 就像你一样。
List<long> myLongList = getLongList();
foreach (var element in myLongList)
{
// ...
}
现在,无论列表的元素类型是什么,我的element
变量都将是相同的类型。耶!
不足之处在于使用非通用 API,例如XmlNode
. 当您向它询问其子节点时,您会得到一个非通用列表。如果您现在使用var
它,系统将无法知道该列表仅包含XmlNode
实例。实际上,它所能做的就是采用非通用方式,并将其var
转换为object
.
简而言之,foreach
由于隐式显式转换(正如我在脑海中所称的那样),您的第一个语句可以正常工作。第二个失败了,因为没有那个演员表,除了 . 之外没有类型信息object
。