集合的参数/返回是否应为IEnumerableT.还是T []? [英] Should parameters/returns of collections be IEnumerable<T> or T[]?

查看:59
本文介绍了集合的参数/返回是否应为IEnumerableT.还是T []?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于我一直采用Linq思维方式,所以我越来越倾向于通过IEnumerable<T>泛型类型遍历集合,该泛型似乎是大多数Linq操作的基础.

As I've been incorporating the Linq mindset, I have been more and more inclined to pass around collections via the IEnumerable<T> generic type which seems to form the basis of most Linq operations.

但是,我想知道,对于IEnumerable<T>泛型类型的最新评估是否是一个好主意.使用T[]泛型类型是否更有意义? IList<T>?还是其他?

However I wonder, with the late evaluation of the IEnumerable<T> generic type if that is a good idea. Does it make more sense to use the T[] generic type? IList<T>? Or something else?

编辑:以下评论非常有趣.尚未解决的一件事似乎是线程安全性问题.例如,如果您对某个方法采用一个IEnumerable<T>参数,并且该参数在另一个线程中被枚举,那么当该线程尝试访问该方法时,其结果可能与本应传递的结果有所不同.更糟糕的是,尝试枚举IEnumerable<T>两次-我相信会引发异常.我们不应该努力使我们的方法具有线程安全性吗?

The comments below are quite interesting. One thing that has not gotten addressed though seems to be the issue of thread safety. If, for example, you take an IEnumerable<T> argument to a method and it gets enumerated in a different thread, then when that thread attempts to access it the results might be different than those that were meant to be passed in. Worse still, attempting to enumerate an IEnumerable<T> twice - I believe throws an exception. Shouldn't we be striving to make our methods thread safe?

推荐答案

我经历了一个绕过T[]的阶段,简而言之,这在后面很痛苦. IEnumerable<T>更好

I went through a phase of passing around T[], and to cut a long story short, it's a pain in the backside. IEnumerable<T> is much better

但是,我想知道,对于IEnumerable泛型类型的最新评估是否是一个好主意.使用T []泛型类型更有意义吗? IList?还是其他的东西

最新评估正是IEnumerable如此出色的原因.这是一个示例工作流程:

Late evaluation is precisely why IEnumerable is so good. Here's an example workflow:

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

对于不耐烦的人,它会获取文件名列表,过滤出.txt文件,然后在任何文本文件包含单词orion的情况下将foundContents设置为true.

For the impatient, this gets a list of filenames, filters out .txt files, then sets the foundContents to true if any of the text files contain the word orion.

如果如上所述使用IEnumerable编写代码,则只会在需要时逐个加载每个文件.您的内存使用量将非常低,如果在第一个文件上进行匹配,则无需查看任何后续文件.很好.

If you write the code using IEnumerable as above, you will only load each file one by one as you need them. Your memory usage will be quite low, and if you match on the first file, you prevent the need to look at any subsequent files. It's great.

如果使用数组编写了完全相同的代码,则最终将所有文件内容都加载到前面,只有到那时(如果还有RAM),才会扫描其中的任何一个.希望这可以弄清楚为什么惰性列表如此之好.

If you wrote this exact same code using arrays, you'd end up loading all the file contents up front, and only then (if you have any RAM left) would any of them be scanned. Hopefully this gets the point across about why lazy lists are so good.

尽管尚未解决的一件事似乎是线程安全性的问题.例如,如果您对某个方法采用一个IEnumerable<T>参数,并且该参数在另一个线程中被枚举,那么当该线程尝试访问该方法时,其结果可能与本应传递的结果有所不同.更糟糕的是,尝试枚举IEnumerable<T>两次-我相信会引发异常.我们不应该努力使我们的方法线程安全吗?

One thing that has not gotten addressed though seems to be the issue of thread safety. If, for example, you take an IEnumerable<T> argument to a method and it gets enumerated in a different thread, then when that thread attempts to access it the results might be different than those that were meant to be passed in. Worse still, attempting to enumerate an IEnumerable<T> twice - I believe throws an exception. Shouldn't we be striving to make our methods thread safe?

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

Thread safety is a giant red herring here.

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

If you used an array rather than an enumerable, it looks like it should be safer, but it's not. Most of the time when people return arrays of objects, they create a new array, and then put the old objects in it. If you return that array, then those original objects can then be modified, and you end up with precisely the kind of threading problems you're trying to avoid.

partial 解决方案是不返回原始对象的数组,而是返回新对象或克隆对象的数组,因此其他线程无法访问原始对象.这很有用,但是没有理由IEnumerable解决方案也不能做到这一点.一个线程比另一个线程安全性更高.

A partial solution is to not return an array of the original objects, but an array of new or cloned objects, so other threads can't access the original ones. This is useful, however there's no reason an IEnumerable solution can't also do this. One is no more threadsafe than the other.

这篇关于集合的参数/返回是否应为IEnumerableT.还是T []?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆