[英]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 => ...);
是的,如果需要,您可能需要将项目IUpdatable
为IUpdatable
,即Enumerable.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());
要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.