LINQ for System.Collections.IEnumerable

时间:2016-09-03 11:37:14

标签: c# linq unity3d

LINQ Where()适用于System.Collections.Generic.IEnumerable<T>,但如果已实现的界面为System.Collections.IEnumerable

,则无法使用

我的问题是,为什么会这样?

更新 也许是一点上下文,我想在Unity的.Where()类上使用Transform,它实现System.Collections.IEnumerable而不是System.Collections.Generic.IEnumerable<Transform>,即使它只有Transforms作为孩子.. 所以我现在为Transform创建了一个扩展方法,随意使用它:

/// <summary> Where-Filter implementation for transform to filter out specific children</summary>
public static IEnumerable<GameObject> WhereChild(this Transform s, Func<GameObject, bool> callback) {
    List<GameObject> r = new List<GameObject>();
    foreach (Transform cur in s) { if (callback(cur.gameObject)) { r.Add(cur.gameObject); } }
    return r;
}

(修改它,如果你想处理变换而不是儿童Gameobjects,我更喜欢这种方式;)

2 个答案:

答案 0 :(得分:4)

因为大多数这些方法都是通用的,当你只获得object时没什么意义。事实上,一些方法 IEnumerable而不是IEnumerable<T>上被声明为扩展方法,例如Cast<T>()OfType<T>,两者都返回一个类型化的可枚举。

因此,在您的情况下,您可以使用Cast<object>()以最无用的方式获得LINQ的好处,因为Where的谓词在没有强制转换的情况下对object无法合理地做很多事情无论如何。

答案 1 :(得分:1)

非通用集合,您无法真正对项目进行任何说明,只有object才能让您编写有用的谓词。这些是linq运营商所必需的。

假设

IEnumerable e = ...;

e.Where( item => ?? ); 

此处item属于object类型,您几乎陷入困境。

另一方面

IEnumerable<Person> e = ...;

e.Where( item => ?? );

在这里,您可以参考实际类型包含的任何成员。

请注意,您始终可以&#34; upcast&#34;集合

IEnumerable e = ...;

e.OfType<Person>().Where( ... )

OfType运算符生成给定类型的非泛型集合的这些项的泛型集合。因此,它允许您引入强类型并在行中使用类型化运算符。