在 foreach 循环中无法识别对象类型 [英] Object type not recognised on foreach loop

查看:38
本文介绍了在 foreach 循环中无法识别对象类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我今天遇到了一个奇怪的问题.

So, i ran into a strange problem today.

假设我有一个 TreeNode 定义如下:

Let's say i have a TreeNode defined like this:

TreeNode node = new TreeNode();
node.Nodes.Add(new TreeNode { Name = "aaa" });
node.Nodes.Add(new TreeNode { Name = "bbb" });

然后我调用一个递归方法

And then I call a recursive method

ColorNode(node.Nodes, Color.Green);

方法如下:

void ColorNode(TreeNodeCollection nodes, System.Drawing.Color Color)
{
    foreach (var child in nodes)
    {
        child.ForeColor = Color;
        if (child.Nodes != null && child.Nodes.Count > 0)
            ColorNode(child.Nodes, Color);
    }
}

在那个 foreach 循环中,如果我保持 var child Visual Studio 哭了

In that foreach loop if I keep var child Visual Studio cries that

对象不包含 ForeColor 的定义,也找不到接受 ojbect 类型的第一个参数的扩展方法 ForeColor.

Object does not contain a definition for ForeColor and no extension method ForeColor accepting a first argument of type ojbect could be found.

object 不包含 Nodes 的定义,也找不到接受类型 object 的第一个参数的扩展方法 Nodes.

object does not contain a definition for Nodes and no extension method Nodes accepting a first argument of type object could be found.

但是如果我将 var child 更改为 TreeNode child,一切都会按预期进行.

But if i change var child with TreeNode child everything works as expected.

有人可以解释这种行为吗?

Can someone explain this behaviour?

推荐答案

正如其他答案中所述,TreeNodeCollectionobject 对象的集合.这是因为 WinForms 从一开始(.NET 1.1)就是 C# 语言的一部分,直到 .NET 2.0 才添加泛型.出于向后兼容的原因,他们没有改变类来实现 IEnumerable.

As is stated in the other answers, TreeNodeCollection is a collection of object objects. This is because WinForms was a part of the C# language from the beginning (.NET 1.1), and generics weren't added until .NET 2.0. For backwards compatibility reasons, they did not alter the class to also implement IEnumerable<TreeNode>.

正如您所发现的,处理它们的唯一方法是在您的 foreach 循环中将对象显式键入为 TreeNode.那是因为 var 直到 .NET 3.5 才被添加.

As you discovered, the only way to process them is by explicitly typing the objects as TreeNode within your foreach loop. That is because var wasn't added until .NET 3.5.

另一种选择(虽然更冗长)是获取您想要的类型的对象:

One other alternative (though more verbose) would be to get the objects of the type that you want:

foreach (var child in nodes.OfType<TreeNode>())

正如我所说,这更冗长,您更适合仅显式转换对象.但是,OfType 方法非常适合您的曲目.

As I said, this is more verbose, and you would be better suited to just explicitly cast the objects. However, the OfType method is a good one to have in your repertoire.

澄清

正如在对 Patrick 的回答的评论中提到的,另一个选项是 .Cast().但是,如果您这样做,如果无法将项目强制转换为指定类型,则会引发异常.在这种情况下,您没有问题,因为根据创建集合的方式,您不会有任何不是 TreeNode 的东西.但是,在其他集合中,可能有基于超类等的其他类型.OfType() 将忽略任何不是您请求的类型的内容.

As mentioned in comments on Patrick's answer, another option is .Cast<T>(). However, if you do that, exceptions are thrown if an item cannot be cast to the specified type. In a situation like this, you are fine because based on the way that the collection is created, you won't have anything that is not a TreeNode. But, in other collections, it is possible to have other types based on super classes, etc. OfType<T>() will ignore anything that is not of the type you are requesting.

这篇关于在 foreach 循环中无法识别对象类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆