C# foreach 接口集合
我想知道 C#/LINQ 中是否内置了任何功能来简化以下内容:
foreach(var item in collection)
{
if (item.GetType() == typeof(Type1)
DoType1(item as Type1);
else if (item.GetType() == typeof(Type2))
DoType2(item as Type2);
...
}
类似于:
collection.ForEachType(Type1 item => DoType1(item), Type2 item => DoType2(item));
我意识到以下内容很接近:
collection.OfType<Type1>.ToList().Foreach(item => DoType1(item));
collection.OfType<Type2>.ToList().Foreach(item => DoType2(item));
但当代码依赖于以下顺序时它不起作用收藏。
I'm wondering if there is any functionality built in to C#/LINQ to simplify the following:
foreach(var item in collection)
{
if (item.GetType() == typeof(Type1)
DoType1(item as Type1);
else if (item.GetType() == typeof(Type2))
DoType2(item as Type2);
...
}
to something along the lines of:
collection.ForEachType(Type1 item => DoType1(item), Type2 item => DoType2(item));
I realize that the following is close:
collection.OfType<Type1>.ToList().Foreach(item => DoType1(item));
collection.OfType<Type2>.ToList().Foreach(item => DoType2(item));
But it does not work when the code is dependent on the order of the collection.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我首先要考虑的是多态性;我可以使用虚拟方法和
item.DoSomething()
吗?接下来我要考虑的是枚举鉴别器,即
(并将鉴别器添加到公共接口/基类)
如果类型可以是任何东西,那么 4.0 有一个技巧;如果您为每个重载调用相同的方法,您可以使用
dynamic
来担心选择它:The first thing I'd look at is polymorphism; can I instead use a virtual method, and
item.DoSomething()
?The next thing I'd look at would be an enum discriminator, i.e.
(and add the discriminator to the common interface/base-class)
If the types could be anything, then 4.0 has a trick; if you call te method the same thing for every overload, you can get
dynamic
to worry about picking it:LINQ 中没有内置任何内容,不是。我会警告您不要像这样使用
GetType()
- 通常使用is
或as
后跟 null 检查更合适:派生类将以通常适当的方式进行处理。
请注意,这种类型测试通常是不受欢迎的 - 通常最好将行为作为虚拟方法放入类型本身,并以多态方式调用它。
There's nothing built into LINQ, no. I would caution you against using
GetType()
like this though - usually it's more appropriate to useis
oras
followed by a null check:That way derived classes will be treated in a way which is usually the appropriate one.
This sort of type testing is generally frowned upon, mind you - it's generally better to put the behaviour into the type itself as a virtual method, and call it polymorphically.
怎么样:
此代码未经测试(直接在浏览器中输入)。
What about something like:
This code is untested (typed directly into the browser).
您的里程可能会有所不同。
这是考虑派生类型的匹配查询的版本(注意,一个项目可能与超过 1 个类型匹配,因此会处理多次)。
Your mileage may vary.
Here's a version of the matching query which considers derived types (Note, an item may be matched to more than 1 type, and therefore handled multiple times).
在我看来,如果您只需将“item.GetType() == typeof( Type1 )”替换为“item is Type1”,您的 foreach 循环就会足够简单。
It seems to me that if you just replace "item.GetType() == typeof( Type1 )" with "item is Type1", your foreach loop will be simple enough.
默认情况下不是。尝试反应式扩展或Elevate
Reactive Extensions 和 Elevate 都包含 ForEach 实现。两者都有相当多的方法来扩展 linq 的功能。
您不会找到 ForEachType,但会找到 ForEach(Rx 或 Elevate)和 OfType<> 。 (Linq) 会给你你想要的。
Not by default. Try Reactive Extensions or Elevate
The Reactive Extensions and Elevate both contain a ForEach implementation. Both have quite a few methods that extend the functionality of linq.
You won't find a ForEachType, but ForEach (Rx or Elevate) and OfType<> (Linq) will give you what you want.