LINQ,列表和添加项目问题

时间:2010-08-12 15:27:49

标签: c# linq list

我有以下是数组

package.Resources

如果我使用

package.Resources.ToList().Add(resouce);

package.Resources实际上并不包含新项目。

我必须使用

var packageList = package.Resources.ToList();
packageList.Add(resource);
package.Resources = packageList.ToArray();

为什么?

4 个答案:

答案 0 :(得分:5)

ToList()根据原始数组创建一个全新的,不同的列表。

LINQ是只读的;语言已整合查询 - 它只查询数据,而不是修改数据。所有LINQ方法都会产生一个投影 - 例如,它们将原始序列投影到一个新的序列中,所以你总是反对它。

答案 1 :(得分:3)

当你致电package.Resources.ToList().Add(resouce);时,它的功能与此相同:

var resourcesAsList = new List<WhateverTypeResourcesContains>();
foreach(var item in package.Resources)
{
    resourcesAsList.Add(item);
}
var resourcesAsList.Add(resouce);

这意味着package.Resources尚未修改,您创建了一个List<T>,其中包含package.Resources包含的每个项目。

答案 2 :(得分:2)

Rex said上,当您在数组对象上调用.ToList()时,您所说的是“让我成为一个全新的List对象,与原始对象截然不同数组,但使用原始数组中的对象作为列表中的对象。“

因为数组的大小是固定的,所以如果没有将现有数组复制到容量增加的新数组(在VB世界副本中为Add()),就无法ReDim Preserve项目在scense背后的阵列)。

因此,如果在实例化时不知道数组中的项目总数,则应该问自己为什么要使用数组。当您知道项目数或从现有ListIEnumerable实例化数组时,数组可以是保存对象集合的轻量级方法。但是,如果您在运行时之前不知道容量并且源不是IEnumerable,则List可能是更好的选择,因为它是为了在添加项目时增加容量而构建的。

我在以下类中使用以下集合类型作为属性:

  • IEnumerable
    • 当我要迭代已经存在的集合时,我使用IEnumerable,我将不会添加它。例如,如果我在目录中查询其文件,并且我希望将这些文件作为类中的属性,我可以使用public IEnumerable<FileInfo> DirectoryFiles {get; set;}
    • IEnumerable允许我查询现有数据集,但我不一定关心它是什么集合,只要它实现IEnumerable
  • List<T>
    • 当我需要一个可以动态增长或缩小的集合时,我使用List<T>,即集合不存在于其他地方,我可能需要添加或删除项目。
    • 如果您允许用户在应用程序的用户界面中添加和删除项目列表框,则可能是一个很好的示例。由于列表框中的项目可能会增大或缩小,因此List<T>有意义。
  • ObservableCollection<T>
    • 我在Silverlight / WPF世界中使用这种类型的集合,因为它具有内置事件,用于何时集合中的项目数量发生变化。当您希望UI元素在列表更改时自动更新时,这对于数据绑定方案尤其方便。

除非我正在使用已经有数组的对象,否则我几乎从不显式使用数组。当然,它们是存储集合的一种很好的轻量级方式,但我通常可以使用上面列出的3种类型。

答案 3 :(得分:1)

属性Resources返回IEnumerableEnumerable.ToList()从此IEnumerable构建列表。然后,您将一个项目添加到新列表,而不是Resources正在访问的原始集合,因此您的更新没有任何影响。