5

cls类型XmlNode

以下语句允许我访问子节点:

foreach (XmlNode child in cls.ChildNodes)

现在,当我尝试使用 var 时:

foreach (var child in cls.ChildNodes)

那么孩子的类型不是XmlNode,只有对象。我不能使用child.NodeType,编译器说:

object'不包含'NodeType'的定义

为什么是这样?

4

2 回答 2

6

ChildNodesXmlNodeList是定义为的类型

public abstract class XmlNodeList : IEnumerable, IDisposable

它的枚举器返回一个object. 当您使用XmlNode代替时var,.net 会自动casts反对XmlNode. 但是当你使用时var,child 被视为一个对象。

于 2013-06-14T11:04:28.487 回答
2

正如我最近自己发现的那样,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

于 2013-06-14T11:21:45.823 回答