Resolved Are arraylists generally used instead of arrays?

WB1975

Well-known member
Joined
Apr 3, 2020
Messages
87
Programming Experience
Beginner
Are arraylists generally used instead of arrays?

I know arraylists are more flexible, but is there any time you would use a standard array instead?
 
ArrayLists aren't used at all any more. Since VB 2005 and .NET 2.0, the generic List<T> effectively replaced the ArrayList, although it can still be used if you want to be wrong.

That's not really the point though. Your question applies either way. Both the ArrayList and List<T> classes exist to effectively provide dynamic array functionality. The point is that those classes provide an array-like data structure that can grow and shrink dynamically as required. That's the reason they exist so, if you don't need that dynamism, there's no reason to use them. Both classes use an array internally anyway so there is an extra layer on top that adds an overhead. If that layer doesn't provide any advantage then why suffer the overhead?

In short, if you want what an array is - a fixed-size list of elements - then use an array. If you need the dynamic resizing that collections provide then use a collection.
 
As I said, both the ArrayList and List<T> classes are wrappers for an array. By default, the internal array has no elements. When you add the first item, a new array with four elements is created and the new item assigned to the first element. As you add further items, the array gets filled. When you add the fifth item, a new array with double the size is created, the existing items are copied from the old array, the new item is assigned to the fifth element and the old array discarded. As you continue to add items and the internal array gets full, the size is doubled each time. This means two things. Firstly, less copying is done that if you "resized" your own array every time you added an item. Secondly, you don't have to keep track of the size of the array or do any of that copying manually.

These are the reasons these collections exist: efficiency and convenience when resizing is required. If you don't need those things, using those collection classes is pointless. An array can do everything that they can do apart from that. They can also do one thing that collections can't. Something that many people don't know is that accessing an element of an array of value types does NOT create a copy. To see this in action, try this code:
C#:
var arr = new[] {new Point(10, 20)};
var lst = new List<Point> {new Point(30, 40)};

Console.WriteLine(arr[0].ToString());
Console.WriteLine(lst[0].ToString());

arr[0].X = 50;
arr[0].Y = 60;

Console.WriteLine(arr[0].ToString());

//lst[0].X = 70;
//lst[0].Y = 80;

//Console.WriteLine(lst[0].ToString());

Console.ReadLine();
If you run that code you'll see that the properties of the Point value in the array are actually modified. I have commented out those three lines because the first two won't even compile, specifically because they can't possibly do anything useful, because they are trying to set properties of copies that would be immediately discarded.

Note that you can also specify an initial capacity for a collection when you create it, which you should do if you know that you'll need at least that many items. That way, the array will be that size to begin with and no resizing will be required until you add more than that many items.
 
My understanding is that the ArrayList was a way to ease Java programmers into C# when C# was first being introduced (as well as the fact that generics were not yet introduced into the language).

Anyway, another reason not to use ArrayLists is that they suffer from boxing and unboxing overhead if you are storing value types (e.g. simple types like integers, characters, doubles, structs) inside it. Since the ArrayList internally uses an array of objects, the runtime needs to wrap up a simple type with an object and then put a pointer to that object inside the list. Later when you need read an item from the array list, it need to get the object and then get the simple type out of the object.
 
Last edited:
My understanding is that the ArrayList was a way to ease Java programmers into C# when C# was first being introduced (as well as the fact that generics were not yet introduced into the language).
That could just be legend. Given who created C#, there'd be no surprise if it had Java-like features. The ArrayList class is part of .NET though, not just C#. Looking at it from a VB perspective, the old VB6 Collection class can behave like an ArrayList or a Hashtable. VB6 had a number of components that have .NET equivalents broken up over multiple classes so, logically, the concept could just as easily have come from VB. The name suggests at least a little Java influence though.
 
Quite possible. I've always revered Anders for Turbo Pascal since that was the language and platform that truly accelerated my learning how to program, but I keep forgetting that he had also worked on J++.
 
Last edited:
And just to preempt your potential follow up question, ArrayList is to List<T> as HashTable is to Dictionary<TKey, TValue>.
 
And just to preempt your potential follow up question, ArrayList is to List<T> as HashTable is to Dictionary<TKey, TValue>.
Indeed. Where you would previously have used members of the System.Collections namespace or maybe System.Collections.Specialized, e.g. StringCollection, now you should use members of the System.Collections.Generic namespace. I always encourage people to read documentation and it's not a bad idea to check out the documentation for that namespace to see what's available. I've seen many a question posted online that could have been avoided if that had been done. You don't have to be solving a specific problem to read documentation. Finding information that may be useful later is one of the best things about reading documentation.
 
Busy reading the documentation for

System.Collections.Generic


" The System.Collections.Generic namespace contains interfaces and classes that define generic collections, which allow users to create strongly typed collections that provide better type safety and performance than non-generic strongly typed collections. "

What are non-generic strongly typed collections?

Classes
TABLE 1
KeyedByTypeCollection<TItem>Provides a collection whose items are types that serve as keys.
SynchronizedCollection<T>Provides a thread-safe collection that contains objects of a type specified by the generic parameter as elements.

Provides a collection whose items are types that serve as keys. - i dont understand this
Provides a thread-safe collection that contains objects of a type specified by the generic parameter as elements. - this too

How is a novice meant to understand this documentation? Am I missing something? Meaning is there a tutorial explaining all this or something.

Is it just a skill you pick up as you go along? I really dont want to be harassing you guys with everything I read in documentation.

Do you understand my dilemma?

please help me understand where is the best place to start to get a good grip of c#, i feel lost at sea so often.
 
What are non-generic strongly typed collections?
While List<T> is the generic collection, a List<string> or List<int> for example are strongly typed collections you create from it - but here I think they meant StringCollection that was mentioned or a strongly typed collection you write yourself by implementing System.Collections.IList.

Notice your link was for version ".Net platform extensions", if you select for example version "Net Framework 4.8" you get a long list of the regular generic classes.

MS Docs contains lots of articles for topics and not just core class documentation, here is one from C# Concepts: Generics - C# Programming Guide
 
Last edited:
In the beginning (.NET Framework 1.1), there were only these strongly type collection:
and these non-strongly typed collections:

At that time, a non-strongly typed collection was anything that took an object a value or a key. As noted above, when you use an object to store things, you could run into the boxing and unboxing overhead. Furthermore, if a collection took just an object, you don't get the benefit of type-safety. Without type safety, you could do something as foolish as:
C#:
var arrayList = new ArrayList();
arrayList.Add(new Human("Luke Skywalker"));
arrayList.Add(new Human("Han Solo"));
arrayList.Add(new Robot("Data"));     // oops!

foreach(Human human in arrayList)
    Console.WriteLine(human);

If ever you programmed in C and you used a generic container library that took void * to hold on to items in the list, it's essentially the same problem of lack of type safety. You have no guarantees that everything inside the list are the same type.
 
What are non-generic strongly typed collections?
I already gave you an example: System.Collections.Specialized.StringCollection.

The ArrayList class is a collection of Object references. There's no way to control what type of objects are added to the collection and, when you get an object out, you get it as an Object reference and have to cast it as its actual type. If you want a collection of String objects then you have to cast each item s type String when you get it out and you can't stop objects that are not Strings being added without writing your own guard code.

The StringCollection class is much like the ArrayList in usage but it will only accept String objects and you get items out as Strings, so no cast is required.

The List<T> class is like ArrayList in usage but you get to decide the type of the items in code. A List<string> will act like a StringCollection but you can also specify any other type for the items too, where you would have had to define your own custom class before the advent of generics. Now, you can create a List<TextBox> if you like, where previously you would have either had to settle for an ArrayList or else define your own class that inherited CollectionBase and write all the TextBox-specific code yourself. That code would, again, be less performant than using List<T> because of all the internal type-checking.
 
Like I said, you can just use a List<T> in most scenarios these days and you have to do zero work to get a collection with items of any specific type. If you wanted your own strongly-typed collection though, e.g. a TextBoxCollection, this is all you would need to do:
C#:
using System.Collections.ObjectModel;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public class TextBoxCollection : Collection<TextBox>
    {
    }
}
You can now use a TextBoxCollection in code. That class will perform well because there's no internal type checking. Courtesy of generics, it's a known fact that every item will be a TextBox so no code has to be written or executed to ensure that. Before generics, a custom TextBoxCollection class would have looked like this:
C#:
using System;
using System.Collections;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public class TextBoxCollection : CollectionBase
    {
        public TextBox this[int index]
        {
            get => (TextBox) List[index];
            set => List[index] = value;
        }

        public int Add(TextBox value)
        {
            return List.Add(value);
        }

        public int IndexOf(TextBox value)
        {
            return List.IndexOf(value);
        }

        public void Insert(int index, TextBox value)
        {
            List.Insert(index, value);
        }

        public void Remove(TextBox value)
        {
            List.Remove(value);
        }

        public bool Contains(TextBox value)
        {
            // If value is not of type TextBox, this will return false.
            return List.Contains(value);
        }

        protected override void OnInsert(int index, object value)
        {
            // Insert additional code to be run only when inserting values.
        }

        protected override void OnRemove(int index, object value)
        {
            // Insert additional code to be run only when removing values.
        }

        protected override void OnSet(int index, object oldValue, object newValue)
        {
            // Insert additional code to be run only when setting values.
        }

        protected override void OnValidate(object value)
        {
            if (value is TextBox)
                throw new ArgumentException("value must be of type TextBox.", nameof(value));
        }
    }
}
As you can see, there is casting and type-checking in there.
 
Back
Top Bottom