c# 中是否有用于在整个集合上调用接口方法的快捷方式



我在一次采访中被问到这个问题。

假设有一个包含项的 c# 集合,所有这些集合都实现一个包含方法 Update(( 的接口 IUpdatable。如何在单个语句(C#中的一行(中对所有项目调用更新方法?

我确实尝试了收集的foreach,并以这种方式在每个项目上调用update((。采访者说,这更像是初级开发人员的风格。他想要一些简短的东西,在一行中。

我当时没有意识到,但这里有 2 种情况。如果集合尚未属于 collection 类型转换步骤,将集合从所述集合<对象>转换为 collection。执行此操作有什么捷径吗?

我不同意你的面试官的观点,因为一些今天看起来很简单的事情明天会让其他开发人员头疼。

我建议使用List<T>.ForEach方法

文档 说:

对列表的每个元素执行指定的操作。

myList.ForEach(p => myFunc(p));但它仅适用于 List<T> ,而不是IList<T>IEnumerable<T>

所以,如果你的收藏不同,你可以做一个这样的技巧myList.ToList().ForEach(e => ...);

更新

是的,如果需要,您可能希望将项目投射到IUpdatableEnumerable.Cast<T>Select(e => (IUpdatable)e)

此外,您可以使用 TPL 和类似Parallel.ForEach

Parallel.ForEach(myList, p =>
{
    //Your stuff
});

但我不确定并行执行是否在桌面上

我希望它有所帮助 😊

面试问题的预期答案:

不应使用 LINQ 调用只会产生副作用的方法。所以最好不要那样做。如果需要,List.ForEach 是当你不关心结果时调用方法的惯用方法,但由于我们有一个可能不是列表的集合,它将需要额外的分配(除了强制转换(:

 collection.Cast<IUpdatable>().ToList().ForEach(x => x.Update());

要投掷,可以使用Enumerable.Cast<T>Enumerable.OfType<T>或仅使用Select(x => (IUpdatable)x)

不太惯用的方法是在常规 LINQ 查询中伪造返回值(如果Update()有,则忽略一个(。请注意,我们需要以某种方式强制评估查询,例如.ToList()或更好的.All()

  collection.Cast<IUpdatable>()
       .Select(x => { x.Update(); return true;})
       .All(x=>x); // to force evaluation without creating extra list

如果集合已经是类型 IEnumerable<IUpdatable>(或派生自 IUpdatable 的任何类型(,则不需要Cast(或OfType(。

如果这将是创建自定义扩展方法的常见操作,该方法明确设计为每个枚举对象调用操作,那么该方法将比前面显示的两个方法更好。

相关内容

最新更新