在c#中,数组列表和List<>有什么区别?
是不是只有List<>有类型而ArrayList没有?
在c#中,数组列表和List<>有什么区别?
是不是只有List<>有类型而ArrayList没有?
当前回答
是的,差不多。List<T>是泛型类。它支持存储特定类型的值,而不强制转换为对象(当T是ArrayList情况下的值类型时,这会引起装箱/拆箱开销)。ArrayList仅存储对象引用。作为一个泛型集合,List<T>实现了泛型IEnumerable<T>接口,可以很容易地在LINQ中使用(不需要任何Cast或OfType调用)。
ArrayList属于c#没有泛型的时代。不赞成使用List<T>。你不应该在以。net >= 2.0为目标的新代码中使用ArrayList,除非你必须与使用它的旧API进行交互。
其他回答
To me its all about knowing your data. If I am continuing to expand my code on the basis of efficiency, I would have to choose the List option as a way of deciphering of my data w/o the unnecessary step of always wondering about types, especially 'Custom Types'. If the machine understands the difference and can determine on it's on what type of data I'm actually dealing with then why should I get in the way and waste time going thru the gyrations of 'IF THEN ELSE' determinations? My philosophy is to let the machine work for me instead of me working on the machine? Knowing the unique differences of different object code commands goes a long way in making your code as efficient.
汤姆•约翰逊 (一项…一个出口)
使用List<T>可以防止强制转换错误。它对于避免运行时强制转换错误非常有用。
例子:
在这里(使用ArrayList),您可以编译这段代码,但稍后会看到一个执行错误。
ArrayList array1 = new ArrayList();
array1.Add(1);
array1.Add("Pony"); //No error at compile process
int total = 0;
foreach (int num in array1)
{
total += num; //-->Runtime Error
}
如果使用List,可以避免以下错误:
List<int> list1 = new List<int>();
list1.Add(1);
//list1.Add("Pony"); //<-- Error at compile process
int total = 0;
foreach (int num in list1 )
{
total += num;
}
参考: MSDN
ArrayList是不同类型数据的集合,而List<>是其自身依赖的相似类型数据的集合。
如.NET Framework文档中所述
我们不建议你将数组列表类用于new 发展。相反,我们建议您使用通用的List<T> 类。ArrayList类被设计用来保存异构类 对象的集合。然而,它并不总是提供最好的 的性能。相反,我们建议如下: 对于异构对象集合,使用List<Object>(在c#中)或List(of Object)(在Visual Basic中)类型。 对于对象的同构集合,使用List<T>类。
请参见不应使用非泛型集合
性能已经在几个答案中被提到作为一个区分因素,但是要解决“数组列表有多慢?”和“为什么整体上更慢?”,请看下面的内容。
当使用值类型作为元素时,ArrayList的性能会急剧下降。考虑简单地添加元素的情况。由于装箱正在进行——因为ArrayList的Add只接受对象参数——垃圾收集器被触发执行比List<T>更多的工作。
时差是多少?至少比List<T>慢几倍。看看在数组列表中添加10mil int值和List<T>的代码会发生什么:
在“均值”列(黄色突出显示)中,这是5倍的运行时间差异。还要注意为每个gc执行的垃圾收集数量的差异,用红色突出显示(每1000次运行没有gc)。
使用分析器快速查看发生了什么,这表明大部分时间都花在了gc上,而不是实际添加元素。下面的棕色条表示阻塞垃圾收集器活动:
我在这里https://mihai-albert.com/2019/12/15/boxing-performance-in-c-analysis-and-benchmark/写了一篇关于上述ArrayList场景的详细分析。
Jeffrey Richter的《CLR via c#》中也有类似的发现。第12章(泛型):
[…] When I compile and run a release build (with optimizations turned on) of this program on my computer, I get the following output. 00:00:01.6246959 (GCs= 6) List<Int32> 00:00:10.8555008 (GCs=390) ArrayList of Int32 00:00:02.5427847 (GCs= 4) List<String> 00:00:02.7944831 (GCs= 7) ArrayList of String The output here shows that using the generic List algorithm with the Int32 type is much faster than using the non-generic ArrayList algorithm with Int32. In fact, the difference is phenomenal: 1.6 seconds versus almost 11 seconds. That’s ~7 times faster! In addition, using a value type (Int32) with ArrayList causes a lot of boxing operations to occur, which results in 390 garbage collections. Meanwhile, the List algorithm required 6 garbage collections.