2014-08-31 45 views
0

例如,我有这样的代码:如何打破源收集和LINQ结果之间的联系

IEnumerable<RSuspectOperationCode> distinctCodes = this.Distinct(); // "this" is some collection 
this.Clear() 
distinctCodes.Count(); 

由于LINQ的延迟执行查询 - 伯爵给我们0我有意思 - 有没有办法通过就地结果计算并打破源和结果集合之间的链接,获得一个独特的集合,清除源集合将不会影响结果集合?

我的解决方法:

List<RSuspectOperationCode> distinctCodes = new List<RSuspectOperationCode>(); 
    distinctCodes.AddRange(this.Distinct(comparer)); 
    this.Clear(); 
    distinctCodes.Count(); 

但是,我不知道,有没有更优雅/短呢?

+0

对不起,通过内存类型代码,mistakened的 – 2014-08-31 07:55:39

+0

可能重复[强制LINQ到不耽误执行] (http://stackoverflow.com/questions/1064043/force-linq-to-not-delay-execution) – 2014-08-31 07:58:05

回答

0

您需要调用某个方法来评估查询。在你的情况下,调用ToArrayToList将通过评估查询并将结果置于新阵列或List<RSuspectOperationCode>中来做你想要的。新列表不会受到您对原始列表所做的任何更改的影响。

请注意,很多人默认使用ToList,这是错误的。不管情况如何,如果你不打算改变列表的长度,那么你应该使用数组而不是集合。这意味着ToArray应该是您的默认选择,只有在您特别需要List<T>时才使用ToList。这不是一个大问题,但你也可以做正确的事情。

+3

*这意味着ToArray应该是您的默认选择*我相信'ToArray'最终可能会比ToList拥有更多的内存分配,因为数组必须是它所代表的集合的确切大小,而List将其容量与其容量尺寸。 http://stackoverflow.com/a/16323412/242520 – 2014-08-31 07:48:00

+1

是的,我知道'List '是如何实现的。 'ToList'和'ToArray'都遵循相同的分配模式,直到最后,在这种情况下,ToList被完成,但如果ToArray分配了一个大于必需的数组,它必须分配另一个数组正确的大小和复制一切到它。所以通过使用'ToList'你可以跳过这个开销。 – 2014-08-31 07:52:59

1

每当您希望立即执行,请致电.ToList()

var distinctCodes= this.Distinct().ToList(); 

this.Clear(); 

var c1 = this.Count(); // 0 

var c2 = distinctCodes.Count(); // eg. 100 
+0

这不会有不同的延期执行。 – brz 2014-08-31 07:58:46

+0

@ user3246354他没有要求在其不同的清单上执行延期执行。他只是想要一个不同的项目清单。 – Vland 2014-08-31 11:32:28

+0

我指的是就地结果计算,“有没有一种方法可以获得具有就地结果计算的独特集合,并打破源和结果集合之间的链接,清除源集合不会影响结果集合?” – brz 2014-08-31 11:34:30

0

我用在LINQ表达式来获取enumeratio做的末尾添加.ToList(),并有收集的副本。

在你的情况,

... = this.Distinct().ToList() 

应该做的伎俩。

1

而不是调用后鲜明的ToList的,所以你必须推迟执行之前把它在不同的列表:

var distinctCodes = this.ToList().Distinct();