ArrayList
和List<>
C#和有什么不一样?
是只有List<>
一种类型而ArrayList
没有吗?
List<>
是一般性的问题,而List<object>
具体是有关的问题
ArrayList
和List<>
C#和有什么不一样?
是只有List<>
一种类型而ArrayList
没有吗?
List<>
是一般性的问题,而List<object>
具体是有关的问题
Answers:
是的,差不多。List<T>
是泛型类。它支持存储特定类型的值,而无需进行强制转换object
(如果T
是值类型,则将产生装箱/拆箱开销ArrayList
)。ArrayList
简单地存储object
引用。作为一个通用的集合,List<T>
实现了通用IEnumerable<T>
接口,并且可以在LINQ容易地使用(而不需要任何Cast
或OfType
呼叫)。
ArrayList
属于C#没有泛型的日子。不推荐使用List<T>
。ArrayList
除非必须与使用它的旧API交互,否则不要在针对.NET> = 2.0的新代码中使用。
ArrayList
运行时相同。不过从静态上来说,它需要使用进行强制转换ArrayList
。
使用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
在64位操作系统花费的时间比使用32位操作系统的2倍的内存。同时,通用列表List<T>
将使用比ArrayList
。低得多的内存。
例如,如果我们ArrayList
在32位中使用19MB的内存,则在64位中将占用39MB的内存。但是,如果您拥有List<int>
32位8MB 的通用列表,那么64位仅需8.1MB,与ArrayList相比,差距是481%。
要添加的另一个区别是关于线程同步。
ArrayList
通过Synchronized属性提供一些线程安全性,该属性返回围绕集合的线程安全包装器。包装器通过在每个添加或删除操作上锁定整个集合来工作。因此,每个试图访问该集合的线程都必须等待其轮换获得一个锁。这是不可扩展的,并且可能导致大型集合的性能显着下降。
List<T>
不提供任何线程同步;在多个线程上同时添加或删除项目时,用户代码必须提供所有同步。
这里更多信息线程同步在.Net框架
ArrayList
如果可以避免就应该使用它,但这是一个愚蠢的原因。毕竟,包装器是完全可选的。如果不需要锁定或需要更精细的控制,请不要使用包装器。
简单的答案是,
ArrayList arrayList = new ArrayList();
List<int> list = new List<int>();
arrayList.Add(1);
arrayList.Add("String");
arrayList.Add(new object());
list.Add(1);
list.Add("String"); // Compile-time Error
list.Add(new object()); // Compile-time Error
请阅读Microsoft官方文档:https : //blogs.msdn.microsoft.com/kcwalina/2005/09/23/system-collections-vs-system-collection-generic-and-system-collections-objectmodel/
注意:在了解差异之前,您应该先了解泛型:https : //docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/generics/
ArrayList
不是类型安全的,List<T>
而是类型安全的。简单:)。
性能已经在几个答案中作为区别因素被提及,但是要解决“ 速度慢多少ArrayList
?”和“ 为什么整体速度变慢?”,请看下面。
每当将值类型用作元素时,使用都会使性能急剧下降ArrayList
。考虑简单添加元素的情况。由于装箱继续-as ArrayList
的Add只带object
参数-垃圾收集器被触发执行比使用垃圾收集器更多的工作List<T>
。
时差是多少?至少比慢几倍List<T>
。只要看看什么用的代码加入10万个INT值的情况ArrayList
VS List<T>
:
在“平均值”列中,运行时间差异为5倍,以黄色突出显示。还要注意每个垃圾收集数量的差异,用红色突出显示(GC数量/ 1000次运行)。
使用探查器快速查看发生的情况表明,大部分时间都花在了GC上,而不是实际添加元素。下面的棕色条表示阻止垃圾收集器的活动:
我在ArrayList
这里https://mihai-albert.com/2019/12/15/boxing-performance-in-c-analysis-and-benchmark/编写了上述情况的详细分析。
杰弗里·里希特(Jeffrey Richter)的“通过C#进行CLR”中也有类似的发现。从第12章(泛型)开始:
[…]当我在计算机上编译并运行此程序的发行版(启用优化功能)时,得到以下输出。
00:00:01.6246959(GCs = 6)列表<Int32>
00:00:10.8555008(GCs = 390)
Array Int32的列表 00:00:02.5427847(GCs = 4)列表<String>
00:00:02.7944831(GCs = 7 )字符串的ArrayList此处的输出显示,将Int32类型的泛型List算法与使用Int32的非泛型ArrayList算法相比要快得多。实际上,两者之间的差异是惊人的:1.6秒和11秒。快约7倍!此外,将值类型(Int32)与ArrayList一起使用会导致发生大量装箱操作,这将导致390个垃圾回收。同时,列表算法需要6个垃圾回收。
我认为ArrayList
和之间的区别List<T>
是:
List<T>
,其中T为value-type比快ArrayList
。这是因为List<T>
避免装箱/拆箱(其中T是值类型)。ArrayList
仅用于向后兼容。(不是真正的区别,但我认为这是重要的注意事项)。ArrayList
再List<T>
ArrayList
拥有IsSynchronized
财产。因此,创建和使用syncronized很容易ArrayList
。我找不到的IsSynchronized
财产List<T>
。还请记住,这种类型的同步效率相对较低(msdn):
var arraylist = new ArrayList();
var arrayListSyncronized = ArrayList.Synchronized(arraylist
Console.WriteLine($"syncronized {arraylist.IsSynchronized}");
Console.WriteLine($"syncronized {arrayListSyncronized.IsSynchronized}");
var list = new List<object>();
var listSyncronized = ArrayList.Synchronized(list);
Console.WriteLine($"syncronized {list.IsSynchronized}");//error, no such prop
Console.WriteLine($"syncronized {list.IsSynchronized}");//error, no such prop
ArrayList
具有ArrayList.SyncRoot
可用于同步(msdn)的属性。List<T>
没有SyncRoot
属性,因此在以下构造中,如果使用,则需要使用一些对象List<T>
:
ArrayList myCollection = new ArrayList();
lock(myCollection.SyncRoot) // ofcourse you can use another object for this goal
{
foreach (object item in myCollection)
{
// ...
}
}
如.NET Framework 文档中所述
我们不建议您将该
ArrayList
类用于新开发。相反,我们建议您使用通用List<T>
类。该ArrayList
课程旨在持有对象的异构集合。但是,它并不总是提供最佳性能。相反,我们建议以下内容:
- 对于异构的对象集合,请使用
List<Object>
(在C#中)或List(Of Object)
(在Visual Basic中)类型。- 对于同质的对象集合,请使用
List<T>
类。
另请参见不应该使用非通用集合
使用“列表”可以防止转换错误。避免运行时强制转换错误非常有用。
例:
在这里(使用ArrayList),您可以编译此代码,但是稍后将看到执行错误。
// Create a new ArrayList
System.Collections.ArrayList mixedList = new System.Collections.ArrayList();
// Add some numbers to the list
mixedList.Add(7);
mixedList.Add(21);
// Add some strings to the list
mixedList.Add("Hello");
mixedList.Add("This is going to be a problem");
System.Collections.ArrayList intList = new System.Collections.ArrayList();
System.Collections.ArrayList strList = new System.Collections.ArrayList();
foreach (object obj in mixedList)
{
if (obj.GetType().Equals(typeof(int)))
{
intList.Add(obj);
}
else if (obj.GetType().Equals(typeof(string)))
{
strList.Add(obj);
}
else
{
// error.
}
}