列表不继承IEnumerable扩展方法

时间:2013-07-01 22:08:44

标签: c# inheritance extension-methods

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

3 个答案:

答案 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();
}