Размер Array задаётся при создании, и за ним надо специально следить. Доступ к нему чуть быстрее, чем к List. Можно получить указатель на элемент через fixed. Если в Array лежат структуры - можно изменить их поля: A[x].B=c;
Элемент массива можно передавать в функцию как ref или out.
Преимущество List в том, что его размер меняется автоматически при добавлении элемента. Менять поля структур в нём нельзя, передавать элементы по ссылке тоже нельзя.
ArrayList - не generic тип (он пришёл ещё из первой версии C#), поэтому состоит только из объектов. С появлением List стал не очень нужен, разве что для случаев, когда действительно нужно хранить объекты разных типов - но и тогда List< object > его полностью заменит.