我有以下代码创建IEnumerable<T>
的扩展程序:
//http://stackoverflow.com/a/1779135/1180926
public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source, int n)
{
//.......
}
当我尝试将其应用于列表时:
public static void RemoveTwo(List<string> strList)
{
strList = strList.SkipLast(2);
}
我收到以下错误:
无法将类型'System.Collections.Generic.IEnumerable'隐式转换为 'System.Collections.Generic.List'。显式转换 存在(你是否错过演员表?)
但是List<T>
继承了IEnumerable<T>
(src),所以不应该继承其扩展方法吗?
答案 0 :(得分:5)
您必须从IEnumerable<string>
:
public static void RemoveTwo(List<string> strList)
{
strList = strList.SkipLast(2).ToList();
}
您的扩展程序返回的IEnumerable<string>
不是List<string>
。但是,如果要修改strList
,则必须使用修改原始集合的Lists
Remove
方法,或者必须返回新列表。
如果您想要更改原始集合而不返回新列表,则应使用RemoveAt
而不是SkipLast
。
public static void RemoveTwo(List<string> strList)
{
if(strList.Count > 0)
strList.RemoveAt(strList.Count-1);
if(strList.Count > 0)
strList.RemoveAt(strList.Count-1);
}
答案 1 :(得分:2)
您的问题不在于调用扩展方法(按原样工作),而在于将IEnumerable<string>
返回值赋给List<string>
变量。为了演示,下面的代码将 work 编译好(但什么都不做):
public static void RemoveTwo(List<string> strList)
{
strList.SkipLast(2);
}
答案 2 :(得分:2)
您所做错的是将返回分配给IEnumerable<string>
返回值的列表。您不能这样做,因为即使所有List<T>
也是IEnumerable<T>
,反之亦然 为真。您需要做的是在ToList()
电话结束时添加 SkipLast
:
public static List<string> RemoveTwo(List<string> strList)
{
return strList.SkipLast(2).ToList();
}