ArrayList and IEnumerable query

Go To StackoverFlow.com

1

Why does the following DisplayContents not work(wont compile) for an ArrayList as it inherits form IEnumerable)

public class Program
    {
        static void Main(string[] args)
        {
            List<int> l = new List<int>(){1,2,3};
            DisplayContents(l);

            string[] l2 = new string[] {"ss", "ee"};
            DisplayContents(l2);

            ArrayList l3 = new ArrayList() { "ss", "ee" };
            DisplayContents < ArrayList>(l3);

            Console.ReadLine();
        }

        public static void DisplayContents<T>(IEnumerable<T> collection)
        {
            foreach (var _item in collection)
            {
                Console.WriteLine(_item);
            }
        }
    }
2012-04-04 18:26
by Noel
What kind of error are you getting - yoozer8 2012-04-04 18:28
Sorry error is "Argument 1: cannot convert from 'System.Collections.ArrayList' to 'System.Collections.Generic.IEnumerable' - Noel 2012-04-04 18:31


7

ArrayList implements IEnumerable, but not the generic IEnumerable<T>. This is to be expected, since ArrayList is neither generic nor bound to any specific type.

You need to change the parameter type of your DisplayContents method from IEnumerable<T> to IEnumerable and remove its type parameter. The items of your collection are passed to Console.WriteLine, which can accept any object.

public static void DisplayContents(IEnumerable collection)
{
    foreach (var _item in collection)
    {
        Console.WriteLine(_item);
    }
}
2012-04-04 18:30
by Douglas
Or better yet, don't use ArrayList at all since it is unnecessary. Use List<object> if you really need to, and the answer to that is probably "no" - Ed S. 2012-04-04 18:31
How does it work for an array then? i.e. it works for string[ - Noel 2012-04-04 18:33
@Noel: arrays implement IEnumerable<T> for their specific type. ArrayList is an outdated type, there was no reason to add another interface to it when generics were introduced - Ed S. 2012-04-04 18:34
string[] implements IEnumerable<string> (as well as ICollection<string> and IList<string>) - Douglas 2012-04-04 18:34
@EdS.: I agree that an ArrayList should be avoided in almost all circumstances - Douglas 2012-04-04 18:35
@Douglas: Yeah I can't think of any good reason to use one aside from being stuck with an old API that uses it - Ed S. 2012-04-04 18:36
@EdS.: That said, there are plenty of APIs still being released today which don’t properly implement inheritance, especially those interfacing with COM. A popular example is the Outlook Object Model; you may get MailItem and DocumentItem objects from the same Folder.Items collection, whose types have no common ancestor despite sharing most properties. The issue was only alleviated with .NET 4’s dynamic keyword - Douglas 2012-04-04 18:41
If you have to work with those APIs, you might be excused for using ArrayList. I’m not aware of the advantages a List<object> would have over it - Douglas 2012-04-04 18:43
@Douglas: The only advantage I see is that it implements IEnumerable<T> :) But yeah, that's what I was saying; you will/should use an ArrayList only when forced to by an API that you do not control - Ed S. 2012-04-04 18:57
You’re right; I’d missed the IEnumerable<T> detail. Which is important since IEnumerable<T> allows you to leverage LINQ (through the <code>Enumerable</code> extension methods) - Douglas 2012-04-04 19:08
Is there a good reason that they haven't made ArrayList implement IEnumerable - Brondahl 2014-07-24 10:09


4

Well, a quick check of the docs tells me that ArrayList does not implement IEnumerable<T>, but instead implements IEnumerable, which makes sense as ArrayList is a vestigial artifact from the days before generics and has few real uses today.

There's really no reason to use ArrayList at all. You can at least use a List<object>, but what problem does that solve? Unless you absolutely need to have a collection of random types that do not / cannot implement a common interface and cannot be grouped into a new type then use a more specific generic parameter.

2012-04-04 18:30
by Ed S.
In other words, DON'T USE ARRAYLIST. Use ListMichael Paulukonis 2012-04-04 18:33
No, seriously. If you are writing code today using ArrayList I WILL SMACK YOU - Michael Paulukonis 2012-04-04 18:34
@MichaelPaulukonis: Yes, please do. I see it too much on forums - Ed S. 2012-04-04 18:34
I don't use ArrayList, I was just messing about and was wondering why it was not workin - Noel 2012-04-04 18:44


0

ArrayList implements IEnumerable, but not generic IEnumerable<T>

UPDATE: This will work:

 public static void DisplayContents(IEnumerable collection)
 {
     foreach (var _item in collection)
         Console.WriteLine(_item);
 }
2012-04-04 18:30
by Sergey Berezovskiy


0

ArrayList l3 = new ArrayList() { "ss", "ee" };             
DisplayContents<ArrayList>(l3); 

Look at your code. You're passing DisplayContents() a list of strings but you're telling it to expect a list of ArrayLists.

You probably meant to just call DisplayContents<string>(l3), but as everyone else has already mentioned, that won't work because ArrayList does not implement the generic IEnumerable<T>, it only implements IEnumerable.

You could instead call

DisplayContents<string>((string[])l3.ToArray(typeof(string)));

This will work because string[] implements IEnumerable<string>.

2012-04-04 18:34
by Igby Largeman


0

How about an extension method?

/// <summary>
/// Projects any <see cref="IEnumerable"/>, e.g. an <see cref="ArrayList"/>
/// to an generic <see cref="IEnumerable{T}"/>.
/// </summary>
/// <typeparam name="T">The type to project to.</typeparam>
/// <param name="source">The source sequence.</param>
/// <param name="map">The mapping function.</param>
/// <returns>A sequence of <typeparamref name="T"/>.</returns>
public static IEnumerable<T> Select<T>(this IEnumerable source, Func<object, T> map)
{
    foreach(var item in source)
    {
        yield return map(item);
    }
}
2018-03-06 11:34
by Jodrell


-3

If you change the calling line to this, it works:

    DisplayContents(l3.ToArray());
2012-04-04 18:33
by Decker97
It works because arrays implement IEnumerable, but that doesn't help the OP understand anything at all - Ed S. 2012-04-04 18:35