C# 将常规列表转换为数组是否有原因/好处?

C# 将常规列表转换为数组是否有原因/好处?,c#,generic-list,C#,Generic List,我有一个返回字符串列表的函数 我可以循环浏览该列表,就像它是一个数组一样 在执行此操作之前,是否有理由将其转换为数组 编辑: 我之所以问这个问题,是因为我在网上看到一些代码(等等),这些代码使用List(或其他类型)操纵/创建字符串集合,但在返回ToArray时调用ToArray,为什么呢?除非您有一个需要它的特定用例。与.NET的开箱即用阵列相比,有更多的操作/搜索列表的选项 如果您使用的是对内存敏感的应用程序,那么阵列的内存占用可能会稍微小一些,但我不会担心这一点,除非内存对于您的应用程序来

我有一个返回字符串列表的函数

我可以循环浏览该列表,就像它是一个数组一样

在执行此操作之前,是否有理由将其转换为数组

编辑:
我之所以问这个问题,是因为我在网上看到一些代码(等等),这些代码使用List(或其他类型)操纵/创建字符串集合,但在返回ToArray时调用ToArray,为什么呢?

除非您有一个需要它的特定用例。与.NET的开箱即用阵列相比,有更多的操作/搜索列表的选项


如果您使用的是对内存敏感的应用程序,那么阵列的内存占用可能会稍微小一些,但我不会担心这一点,除非内存对于您的应用程序来说是一个非常敏感的问题。

一个原因是确保您没有向客户端代码公开原始列表。如果您没有公开,则他们可能会向返回的
列表添加/删除元素,这将修改源列表,因为
列表
是引用类型。这可能不是预期的行为

如果使用
ToArray
并返回数组,则无需担心数组中的修改,因为它只是数据的一个副本


如果您对一些示例代码有一些特定的问题,您可能会得到一个特定的答案。

一个原因是您使用类作为缓存,例如,一个类具有所有客户端的字段列表,并且您希望返回如下所示的子集

List<Clients> _listOfClientCache ; 

private client[] GetSClientsByCity(string city)
{
   _listOfClient.Where(x => x.Client.City = city).ToArray();
}
List\u客户机列表;
私人客户端[]GetSClientsByCity(字符串城市)
{
_listOfClient.Where(x=>x.Client.City=City.ToArray();
}
我看到的一个原因是内存足迹,若调用者不打算添加或删除元素,那个么它会节省内存

列表是使用数组实现的,但当需要添加大于下划线数组大小的元素时,它只会将基础数组的大小加倍,并复制元素。因此,底层数组的大小很可能大于列表中的实际元素

转换为数组将释放为未使用的元素分配的内存

下面是测试

[TestMethod]
    public void ListAndArrayTest()
    {
        int[] array = GetArray();
        Debug.WriteLine("IsFixedSize {0}, Elements {1}", array.IsFixedSize, array.Length);
// This will print IsFixedSize True, Elements 35
    }

    private int[] GetArray()
    {
        List<int> localList = new List<int>();
        for (int i = 0; i < 35; i++)
        {
            localList.Add(i);
        }
        Debug.WriteLine("Capacity {0}, Element Count {1}", localList.Capacity, localList.Count);
        // This will print Capacity **64**, Element Count **35**
        return localList.ToArray();
    }
[TestMethod]
公共无效列表和阵列测试()
{
int[]数组=GetArray();
WriteLine(“IsFixedSize{0},Elements{1}”,array.IsFixedSize,array.Length);
//这将打印IsFixedSize True,元素35
}
私有int[]GetArray()
{
List localList=新列表();
对于(int i=0;i<35;i++)
{
localList.Add(i);
}
WriteLine(“容量{0},元素计数{1}”,localList.Capacity,localList.Count);
//这将打印容量**64**,元素计数**35**
返回localList.ToArray();
}
输出:容量64,元素计数35 IsFixedSize为真,元素35

从输出中可以清楚地看出,调用者使用的是纯数组,而不是原始列表的任何引用,该列表在引擎盖下使用了容量为64个元素的数组,而在32个元素之后,当它需要更多元素时,它将数组的大小加倍到64个,并将元素复制到其中


一旦转换回数组,调用者就拥有35个元素的数组。

数组比列表更轻量级,并且不提供实际的操作方法
(我所说的操作是指:添加和删除项)

要向数组中添加项或从数组中删除项,需要重新定义数组

列表允许您使用.Add和.Remove等方法—使它们更适合于集合操纵结构

如果您的需求只关注于在集合中查找一个项,请坚持使用数组,但如果您需要操作集合,请使用列表


将列表想象成操作数组的特殊接口。

您看到的示例代码可能会执行某种惰性计算(例如大多数Linq语句)。 在这种情况下,将结果转换为数组以立即执行查询而不是在第一次迭代中对其求值是有意义的

例如:

// persons will only be lazy evaluated, which means
// the query will only execute when the "persons" are iterated.
var persons = Persons.Select(x => x.Name == "John Doe");

// here the "ToArray" forces an immediate execution of the query
var personsArray = Persons.Select(x => x.Name == "John Doe").ToArray();

不,只是遍历列表。我不想知道什么时候使用列表或数组,我已经在使用列表了,因为我需要(.add function),但为什么我要在之后将其转换为数组?如果将列表传递给一个需要数组的方法,则需要将其转换为数组。我不认为这是重复的;这个问题特别询问一个
列表
已经存在,并在迭代之前转换为数组的情况。投票重新打开。您是否可以显示一个创建这样一个集合的代码示例,然后在返回集合之前调用
ToArray
?我可以想到这样做的各种原因,但我更愿意针对特定类型的情况回答这个问题,而不是仅仅根据可能的情况或可能的情况进行胡乱猜测。它们仍然可以替换返回数组中的项-数组也是引用类型-因此在这方面并不真正安全。创建列表的副本确实可以保护原始的内部列表不受此类更改的影响,但是,该副本也可以是一个列表,也可以是一个数组。因此,是否返回内部列表副本的决定独立于返回数组或列表的决定。@O.R.Mapper同意您的意见,您返回的
array
list
并不重要,重要的是它是副本还是原件。但是
ToArray
是返回数据副本的最常见的方法。在某些情况下,这是一种更干净的方法,可以防止内部列表发生不受控制的更改。我们需要查看OP的一些代码来说明什么是合适的,什么是不合适的。可写索引器相当于一种“操纵方法”,你说呢?而且,这并不能回答这个问题,为什么它会或不会有用