繁体   English   中英

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

[英]Is there a shortcut in c# to invoke a interface method on an entire collection?

采访中有人问我这个问题。

假设有一个ac#集合,其中包含项,所有这些项都实现一个包含方法Update()的接口IUpdatable。 一个人如何在单个语句中调用所有项目的update方法,而在c#中是一个班轮?

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

当时我没有意识到,但是这里有2种情况。 如果该集合的类型不是collection <IUpdatable>,则首先需要执行类型转换步骤,以将集合从say collection <object>转换为collection <IUpdatable>。 任何执行此操作的快捷方式?

我不同意您的面试官,因为今天看起来很简单的某些事情会在明天对其他开发人员造成困扰。

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

文档说:

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

myList.ForEach(p => myFunc(p)); 但是它仅在List<T>上可用,在IList<T>IEnumerable<T>不可用

因此,如果您的集合不同,则可以执行类似myList.ToList().ForEach(e => ...);的技巧myList.ToList().ForEach(e => ...);

更新资料

是的,如果需要,您可能需要将项目IUpdatableIUpdatable ,即Enumerable.Cast<T>Select(e => (IUpdatable)e)

另外,您可以使用TPLParallel.ForEach东西

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

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

希望对您有帮助

面试问题的预期答案:

人们不应该使用LINQ来调用只会产生副作用的方法。 因此,最好不要这样做。 如果需要,则List.ForEach是不关心结果时调用方法的惯用方式,但是由于我们有一个可能不是列表的集合,因此需要额外的分配(除了强制转换):

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

Select(x => (IUpdatable)x) ,可以使用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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM