为什么我应该调用ArrayList.ToArray方法?

3

我是一个有帮助的助手,可以为您进行翻译。以下是需要翻译的内容:

我工作所在的代码库中,在几个地方都有类似以下代码:

Dim i As Integer
Dim ints As New ArrayList
ints.Add(1)

'... lets say we add more Integers

For each i in ints.ToArray(GetType(Integer))
'Do something
Next

我想知道在运行时省略 .ToArray(GetType(Integer)) 与使用它相比有什么好处。也就是说,调用 For Each i In ints。我发现唯一的区别是,如果除了整数之外的某些类型出现在 ArrayList 中,则如果您不调用.ToArray(),则会得到更有帮助的错误消息。
如果已经指定了类型,为什么要在 ArrayList 上使用 ToArray(type) 来执行 For Each 循环呢?

你不会希望调用 ToArray,除非你需要一个数组,比如将其传递给一个只接受 Integer() 作为参数的方法。 - vcsjones
1
也许他们想尽早强制出错误,如果“ints”包含非整数。例如,如果你有1000个项目在那里,最好在开始时失败而不是在第999个元素处失败。 - Markku K.
你为什么一开始要使用ArrayList呢? List(Of T) 在任何可能的方面都更好。 - Joel Coehoorn
@JoelCoehoorn 我不知道。就我所看到的,没有理由。可能是无知? - Daniel
我猜这个代码库可能是老旧的,在 .Net 2 引入泛型之前就开始了很多工作。 - Joel Coehoorn
1
@MarkkuK。这是一个很好的观点。在执行任何循环代码之前失败可能是一个显著的改进。 - Daniel
5个回答

5
如果在已经指定类型的情况下使用ArrayListToArray(type)将会有哪些好处呢?一般来说,你可能不需要这么做。调用ToArray()实际上会创建一个新的包含你的值的数组。唯一一个有用的地方就是如果你想要修改ArrayList中的元素,你不能在枚举时进行修改,否则会抛出异常。通过添加ToArray调用,你可以枚举该集合(转换为数组)的副本,从而可以修改原始集合。需要注意的是,一般情况下,如果是这种情况,我会使用ToList()而不是ToArray(),因为它通常更有效率(通常减少了一个内存分配)。对于任何新代码,我也建议使用List(Of Integer)而不是ArrayList,因为它提供了类型安全性。

同意。我本来会提到我不会一开始就使用ArrayList,但感觉那是另一个问题了。 - Daniel

2

For each循环中,您不需要对ArrayList调用ToArray:已经声明了iInteger,因此类型转换将自动执行。

有时您可能需要在查询结果上调用数组以将数据复制到内存中。其中一个优势是将数据库查询结果复制到内存中,因为可以更早地关闭连接。此外,在查询会多次引用修改后的变量或IEnumerable较昂贵的情况下,调用ToList可以帮助您。


i 是一个整数,但 ints 可能是其他类型。 - user195488
@0A0D ints 可能是其他类型,但如果不兼容,ToArrayFor each 都会失败。假设 ToArray 不会失败,那么 For each 也不应该失败。 - Sergey Kalinichenko
你能通过使用 GetTypelong 强制转换为 int 吗?我不知道。 - user195488
我的VB经验相对有限,但我几乎可以肯定,在ints内部使用long会导致ToArrayFor each都失败。 - Sergey Kalinichenko
我认为你是正确的。GetType 似乎是用于相等性检查,而不是像这段代码的原始作者可能意图的那样更改类型。 - user195488
根据[MSDN](http://msdn.microsoft.com/en-us/library/vstudio/5ebk1751.aspx),您可以使用Integer遍历longs数组,但是如果值溢出Integer,则会出现异常。从该页面中,以下内容是正确的:`For Each number As Integer In New Long() {45, 3, 987}` - Markku K.

1

你可能会在 ArrayList 上调用 .ToArray() 的两个原因:

  1. 这样你就不需要对 ArrayList 中的项进行强制类型转换。数组是强类型的,因此首先将它们放在那里意味着编译器知道 ArrayList 中的所有内容都是整数。
  2. 这样你就可以将 ArrayList 传递给期望一个数组作为参数的方法。

1
在旧的代码库中进行防御性编程。假设当时没有“List(Of Integer)”可用。有几个原因你希望在“For Each”语句中失败(如果“ints”包含非整数),而不是在循环后面:
  1. 显然,你不想浪费时间。循环内部的操作可能需要很长时间。最好在开始循环之前失败,而不是在第99999次迭代时。
  2. 你可能希望对整个ArrayList执行“全部或无”。

1
在您的情况下,更改为此代码即可,无需:
Dim i As Integer
Dim ints As New Generic.List(Of Integer)
ints.Add(1)
'... lets say we add more Integers

For each i in ints
'Do something
Next

ToArray 在处理 LINQ 结果时非常方便。如果你的集合大小是可测量的,你可以使用 ToArray。大多数旧的 .NET 函数更喜欢使用数组。一个很好的例子就是 String.Join。因此,你可能需要经常使用它来保持调用之间的类型兼容性。另一个这样做的原因是数组在调试器中更容易检查。

无论如何,你都应该始终证明其必要性。如果你的目标是严格类型化,最好使用专为此目的创建的类型,例如上面的 Generic.List(Of T)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接