为什么以下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);
}
}
}
答案 0 :(得分:7)
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);
}
}
。
{{1}}
答案 1 :(得分:4)
好吧,快速检查the docs告诉我ArrayList
没有实现IEnumerable<T>
,而是实现IEnumerable
,这是有道理的ArrayList
是ArrayList
来自仿制药前几天的遗留神器,今天几乎没有真正的用途。
根本没有理由使用List<object>
。您至少可以使用{{1}},但这会解决哪些问题?除非您绝对需要一组无法/不能实现公共接口且无法分组为新类型的随机类型,否则请使用更具体的通用参数。
答案 2 :(得分:0)
ArrayList
实施IEnumerable
,但不是通用IEnumerable<T>
更新: 这将有效:
public static void DisplayContents(IEnumerable collection)
{
foreach (var _item in collection)
Console.WriteLine(_item);
}
答案 3 :(得分: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>
。
答案 4 :(得分: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);
}
}
答案 5 :(得分:-3)
如果您将主叫行更改为此,则可以:
DisplayContents(l3.ToArray());