当前位置:  开发笔记 > 程序员 > 正文

集合的参数/返回应该是IEnumerable <T>还是T []?

如何解决《集合的参数/返回应该是IEnumerable<T>还是T[]?》经验,为你挑选了2个好方法。

由于我一直在整合Linq思维模式,我越来越倾向于通过IEnumerable泛型类型传递集合,这似乎构成了大多数Linq操作的基础.

但是我想知道,对于IEnumerable泛型类型的后期评估,如果这是一个好主意.使用T[]泛型类型更有意义吗? IList?或者是其他东西?

编辑: 以下评论非常有趣.有一件事虽然没有得到解决,但似乎是线程安全问题.例如,如果你接受IEnumerable一个方法的参数并且它在另一个线程中被枚举,那么当该线程试图访问它时,结果可能与那些本来要传入的结果不同.更糟糕的是,试图枚举一IEnumerable两次-我相信抛出一个异常.我们难道不应该努力使我们的方法线程安全吗?



1> Orion Edward..:

我经历了一个绕过的阶段,T[]长话短说,这是背后的痛苦.IEnumerable好多了

但是我想知道,对于IEnumerable泛型类型的后期评估,如果这是一个好主意.使用T []泛型类型更有意义吗?IList的?或者是其他东西

后期评估正是为什么IEnumerable这么好.这是一个示例工作流程:

IEnumerable files = FindFileNames();
IEnumerable matched = files.Where( f => f.EndsWith(".txt") );
IEnumerable contents = matched.Select( f => File.ReadAllText(f) );
bool foundContents = contents.Any( s => s.Contains("orion") );

对于不耐烦的人,这会得到一个文件名列表,过滤掉.txt文件,然后foundContents如果任何文本文件包含该单词,则设置为true orion.

如果您使用IEnumerable上述代码编写代码,则只会根据需要逐个加载每个文件.您的内存使用率非常低,如果您匹配第一个文件,则无需查看任何后续文件.这很棒.

如果你使用数组编写完全相同的代码,你最终会预先加载所有文件内容,然后才会(如果你有任何RAM)将扫描它们中的任何一个.希望这可以解释为什么懒惰列表如此优秀.

有一件事虽然没有得到解决,但似乎是线程安全问题.例如,如果你接受IEnumerable一个方法的参数并且它在另一个线程中被枚举,那么当该线程试图访问它时,结果可能与那些本来要传入的结果不同.更糟糕的是,试图枚举一IEnumerable两次-我相信抛出一个异常.我们难道不应该努力使我们的方法线程安全吗?

线程安全在这里是一个巨大的红鲱鱼.

如果您使用的是数组而不是可枚举的数组,那么它看起来应该更安全,但事实并非如此.大多数情况下,当人们返回对象数组时,他们会创建一个新数组,然后将旧对象放入其中.如果你返回那个数组,那么那些原始对象就可以被修改,你最终会得到你想要避免的那种线程问题.

部分解决方案是不会返回原来的对象的数组,但新的或克隆对象的数组,所以其他线程不能访问原有的.这很有用,但是IEnumerable解决方案也没有理由不这样做.一个不比另一个更安全.



2> Jay Bazuzi..:

在大多数情况下,您不应该T[]public接口上传递arrays().有关详细信息,请参阅Eric Lippert的博客文章" Arrays被视为有害 ".

例外是采用params数组的方法,因为它必须是一个数组.(希望将来的版本允许params IList foo在方法签名中使用" ".)

对于internal会员,做任何你喜欢的事; 你可以控制界面的两面.

推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有