2

我有以下代码创建一个扩展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),所以它不应该也继承它的扩展方法吗?

4

3 回答 3

5

您必须从以下位置创建一个列表IEnumerable<string>

public static void RemoveTwo(List<string> strList)
{
    strList = strList.SkipLast(2).ToList();
}

您的扩展返回IEnumerable<string>不是List<string>. 但是,如果要修改strList,则必须使用Lists类似Remove修改原始集合的方法,否则必须返回新列表。

如果您想更改原始集合而不返回新列表,则应该SkipLast使用。RemoveAt

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);
}
于 2013-07-01T22:10:32.680 回答
2

您的问题不在于调用扩展方法(按原样工作),而在于将其IEnumerable<string>返回值分配给List<string>变量。为了演示,以下代码可以正常编译(但什么也不做):

public static void RemoveTwo(List<string> strList)
{
    strList.SkipLast(2);
}
于 2013-07-01T22:11:32.087 回答
2

您做错的是将返回值分配列表IEnumerable<string>。你不能这样,因为即使所有List<T>s 也是IEnumerable<T>,反之亦然。您需要做的是在通话结束时添加一个:ToList()SkipLast

public static List<string> RemoveTwo(List<string> strList)
{
    return strList.SkipLast(2).ToList();
}
于 2013-07-01T22:12:41.603 回答