ArrayList and IEnumerable query

本文关键字:query IEnumerable and ArrayList | 更新日期: 2023-09-27 18:30:14

为什么下面的 DisplayContents 对 ArrayList 不起作用(不会编译(,因为它继承了 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);
            }
        }
    }

ArrayList and IEnumerable query

ArrayList实现IEnumerable,但不是泛型IEnumerable<T>。这是意料之中的,因为ArrayList既不是泛型的,也不是绑定到任何特定类型的。

您需要将DisplayContents方法的参数类型从 IEnumerable<T> 更改为IEnumerable并删除其类型参数。您收藏的项目将传递给Console.WriteLine,它可以接受任何object

public static void DisplayContents(IEnumerable collection)
{
    foreach (var _item in collection)
    {
        Console.WriteLine(_item);
    }
}

好吧,快速检查文档告诉我ArrayList没有实现IEnumerable<T>,而是实现IEnumerable,这是有道理的,因为ArrayList是泛型之前的遗留工件,今天几乎没有实际用途。

真的根本没有理由使用ArrayList。 你至少可以使用List<object>,但这能解决什么问题呢? 除非您绝对需要有一个随机类型的集合,这些随机类型不/不能实现公共接口并且不能分组到新类型中,否则请使用更具体的泛型参数。

>ArrayList实现IEnumerable,但不是泛型IEnumerable<T>

更新:这将起作用:

 public static void DisplayContents(IEnumerable collection)
 {
     foreach (var _item in collection)
         Console.WriteLine(_item);
 }
ArrayList l3 = new ArrayList() { "ss", "ee" };             
DisplayContents<ArrayList>(l3); 

查看您的代码。您正在传递DisplayContents()字符串列表,但您告诉它需要 ArrayList 列表。

您可能只想调用DisplayContents<string>(l3),但正如其他人已经提到的,这是行不通的,因为 ArrayList 不实现泛型IEnumerable<T>,它只实现IEnumerable

您可以改为致电

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

这将起作用,因为string[]实现了IEnumerable<string>

扩展方法怎么样?

/// <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);
    }
}

如果将呼叫线路更改为此线路,它将起作用:

    DisplayContents(l3.ToArray());