1

为什么以下 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);
            }
        }
    }
4

6 回答 6

7

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

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

public static void DisplayContents(IEnumerable collection)
{
    foreach (var _item in collection)
    {
        Console.WriteLine(_item);
    }
}
于 2012-04-04T18:30:31.903 回答
4

好吧,对文档的快速检查告诉我,ArrayList它没有实现IEnumerable<T>,而是实现了IEnumerable,这是有道理的,因为ArrayList从泛型之前的日子开始,这是一个残留的人工制品,今天几乎没有真正的用途。

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

于 2012-04-04T18:30:14.853 回答
0

ArrayList实现IEnumerable,但不是通用的IEnumerable<T>

更新:这将起作用:

 public static void DisplayContents(IEnumerable collection)
 {
     foreach (var _item in collection)
         Console.WriteLine(_item);
 }
于 2012-04-04T18:30:04.367 回答
0
ArrayList l3 = new ArrayList() { "ss", "ee" };             
DisplayContents<ArrayList>(l3); 

看看你的代码。您正在传递DisplayContents()一个字符串列表,但您告诉它期望一个 ArrayLists 列表。

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

你可以改为打电话

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

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

于 2012-04-04T18:34:17.820 回答
0

扩展方法怎么样?

/// <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-06T11:34:32.447 回答
-3

如果您将呼叫线路更改为此,它可以工作:

    DisplayContents(l3.ToArray());
于 2012-04-04T18:33:07.940 回答