Qual é a diferença entre ArrayListeList<> em c #?
É apenas que List<>tem um tipo enquanto ArrayListnão?
List<>em geral, enquanto que uma pergunta sobre List<object>especificamente
Qual é a diferença entre ArrayListeList<> em c #?
É apenas que List<>tem um tipo enquanto ArrayListnão?
List<>em geral, enquanto que uma pergunta sobre List<object>especificamente
Respostas:
Sim, praticamente. List<T>é uma classe genérica. Ele suporta o armazenamento de valores de um tipo específico sem conversão para ou de object(o que teria incorrido em sobrecarga de boxe / unboxing quando Té um tipo de valor no ArrayListcaso). ArrayListsimplesmente armazena objectreferências. Como uma coleção genérica, List<T>implementa o genérico IEnumerable<T>de interface e pode ser usado facilmente em LINQ (sem necessidade de qualquer Castou de OfTypechamada).
ArrayListpertence aos dias em que o C # não tinha genéricos. Está obsoleto em favor de List<T>. Você não deve usar um ArrayListnovo código que tenha como alvo .NET> = 2.0, a menos que tenha que fazer interface com uma API antiga que a usa.
ArrayListno tempo de execução. Estaticamente, porém, será necessário um elenco ArrayList.
Usando List<T>você pode evitar erros de conversão. É muito útil evitar um tempo de execução erro de conversão de execução.
Exemplo:
Aqui (usando ArrayList) você pode compilar esse código, mas você verá um erro de execução posteriormente.
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
}
Se você usar List, evite estes erros:
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;
}
Referência: MSDN
Para adicionar aos pontos acima. O uso ArrayListno sistema operacional de 64 bits requer 2x memória do que o uso no sistema operacional de 32 bits. Enquanto isso, a lista genérica List<T>usará muito pouca memória que aArrayList .
por exemplo, se usarmos um ArrayListde 19 MB em 32 bits, serão necessários 39 MB nos 64 bits. Mas se você tiver uma lista genéricaList<int> de 8 MB em 32 bits, serão necessários apenas 8,1 MB em 64 bits, que é uma diferença gritante de 481% quando comparado ao ArrayList.
Fonte: lista ArrayList vs. genérica para tipos primitivos e 64 bits
Outra diferença a ser adicionada é com relação à sincronização de threads.
ArrayListfornece alguma segurança de thread através da propriedade Synchronized, que retorna um wrapper seguro de thread em torno da coleção. O wrapper funciona bloqueando a coleção inteira em todas as operações de adição ou remoção. Portanto, cada encadeamento que está tentando acessar a coleção deve aguardar sua vez de bloquear o único bloqueio. Isso não é escalável e pode causar degradação significativa no desempenho de grandes coleções.
List<T>não fornece nenhuma sincronização de encadeamento; o código do usuário deve fornecer toda a sincronização quando itens são adicionados ou removidos em vários threads simultaneamente.
Mais informações aqui Sincronização de threads no .Net Framework
ArrayListse puder ser evitado, mas esse é um motivo bobo. O wrapper é totalmente opcional, afinal; se você não precisar de bloqueio ou se precisar de mais controle granular, não use o wrapper.
Resposta simples é,
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
Leia o documento oficial da Microsoft : https://blogs.msdn.microsoft.com/kcwalina/2005/09/23/system-collections-vs-system-collection-generic-and-system-collections-objectmodel/
Nota : Você deve conhecer os Genéricos antes de entender a diferença: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/
ArrayListé a coleta de tipos diferentes de dados, enquanto List<>a coleta de tipos semelhantes de suas próprias dependências.
ArrayListnão são do tipo seguro, enquanto List<T>são do tipo seguro. Simples :).
O desempenho já foi mencionado em várias respostas como um fator diferenciador, mas para abordar a questão “ Quanto mais lento é o ArrayList? ”E“ Por que é mais lento no geral?”, Dê uma olhada abaixo.
Sempre que tipos de valor são usados como elementos, o desempenho diminui drasticamente ArrayList. Considere o caso de simplesmente adicionar elementos. Devido ao boxe - como ArrayListo Add adiciona apenas objectparâmetros - o Garbage Collector é acionado para executar muito mais trabalho do que comList<T> .
Quanto é a diferença horária? Pelo menos várias vezes mais lento que com List<T>. Basta dar uma olhada no que acontece com o código adicionando 10 mil int valores a um ArrayListvs List<T>:

Essa é uma diferença de tempo de execução de 5x na coluna "Média", destacada em amarelo. Observe também a diferença no número de coletas de lixo feitas para cada uma, destacadas em vermelho (sem GCs / 1000 execuções).
O uso de um criador de perfil para ver o que está acontecendo rapidamente mostra que a maior parte do tempo é gasta na criação de GCs , em vez de realmente adicionar elementos. As barras marrons abaixo representam o bloqueio da atividade do Garbage Collector:

Escrevi uma análise detalhada do que se passa com o ArrayListcenário acima aqui https://mihai-albert.com/2019/12/15/boxing-performance-in-c-analysis-and-benchmark/ .
Resultados semelhantes estão em "CLR via C #", de Jeffrey Richter. Do capítulo 12 (Genéricos):
[…] Ao compilar e executar uma compilação de versão (com otimizações ativadas) deste programa no meu computador, recebo a seguinte saída.
00: 00: 01.6246959 (GCs = 6) Lista <Int32>
00: 00: 10.8555008 (GCs = 390) ArrayList of Int32
00: 00: 02.5427847 (GCs = 4) Lista <String>
00: 00: 02.7944831 (GCs = 7 ) ArrayList de StringA saída aqui mostra que o uso do algoritmo List genérico com o tipo Int32 é muito mais rápido do que o uso do algoritmo ArrayList não genérico com o Int32. De fato, a diferença é fenomenal: 1,6 segundos versus quase 11 segundos. Isso é ~ 7 vezes mais rápido ! Além disso, o uso de um tipo de valor (Int32) com ArrayList causa muitas operações de boxe, o que resulta em 390 coletas de lixo. Enquanto isso, o algoritmo List exigia 6 coletas de lixo.
Eu acho que as diferenças entre ArrayListe List<T>são:
List<T>, onde T é do tipo valor é mais rápido que ArrayList. Isso ocorre porque List<T>evita boxe / unboxing (onde T é do tipo valor).ArrayListusadas apenas para compatibilidade com versões anteriores. (não é uma diferença real, mas acho que é uma nota importante).ArrayListseguidaList<T>ArrayListtem IsSynchronizedpropriedade. Portanto, é fácil criar e usar sincronizado ArrayList. Não encontrei IsSynchronizedpropriedades para List<T>. Lembre-se também de que esse tipo de sincronização é relativamente ineficiente, 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 propArrayListpossui ArrayList.SyncRootpropriedade que pode ser usada para sincronização ( msdn ). List<T>não possui SyncRootpropriedade, portanto, na construção a seguir, você precisará usar algum objeto se usar List<T>:
ArrayList myCollection = new ArrayList();
lock(myCollection.SyncRoot) // ofcourse you can use another object for this goal
{
foreach (object item in myCollection)
{
// ...
}
}Conforme mencionado na documentação do .NET Framework
Não recomendamos que você use a
ArrayListclasse para novos desenvolvimentos. Em vez disso, recomendamos que você use aList<T>classe genérica . AArrayListclasse foi projetada para armazenar coleções heterogêneas de objetos. No entanto, nem sempre oferece o melhor desempenho. Em vez disso, recomendamos o seguinte:
- Para uma coleção heterogênea de objetos, use o tipo
List<Object>(em C #) ouList(Of Object)(no Visual Basic).- Para uma coleção homogênea de objetos, use a
List<T>classe
Consulte também Coleções não genéricas não devem ser usadas
Usando a "Lista", você pode evitar erros de conversão. É muito útil evitar um erro de conversão de tempo de execução.
Exemplo:
Aqui (usando ArrayList) você pode compilar esse código, mas você verá um erro de execução posteriormente.
// 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.
}
}
Para mim, é tudo uma questão de conhecer seus dados. Se eu continuar expandindo meu código com base na eficiência, teria que escolher a opção Lista como uma maneira de decifrar meus dados sem a etapa desnecessária de sempre me perguntar sobre tipos, especialmente 'Tipos personalizados'. Se a máquina entende a diferença e pode determinar com que tipo de dados estou realmente lidando, por que devo atrapalhar e perder tempo passando pelas variações das determinações "SE ENTÃO MAIS"? Minha filosofia é deixar a máquina trabalhar para mim em vez de trabalhar na máquina? Conhecer as diferenças exclusivas de diferentes comandos de código de objeto ajuda bastante a tornar seu código tão eficiente.
Tom Johnson (uma entrada ... uma saída)