Visual Studio 2005:C#中List<T>.First()和List<T>.Last()方法是什么?

4

我在我的VS 2008 C#项目中使用了 List<T>.First()List<T>.Last(),但是当我降级到2005时,出现了以下错误:

'System.Collections.Generic.List' 不包含 'First' 的定义

据我所知,如果仍然存在 Find()FindLast() 方法,那么一定有一种非常简单的方法来获取迭代器到第一个和最后一个值,是吗?但是我卡在这里,找不到任何有用的东西 :(

4个回答

11

First()Last()是LINQ的一部分,所以它们在您的VS 2005项目中找不到。

如果您正在使用List<T>,假设列表不为空,查找第一个和最后一个值非常容易:

T first = list[0];
T last = list[list.Count-1];

如果你真的需要使用迭代器,你可以非常容易地实现LINQ方法:

public static T First<T>(IEnumerable<T> source)
{
    foreach (T element in source)
    {
        return element;
    }
    throw new InvalidOperationException("Empty list");
}

public static T Last<T>(IEnumerable<T> source)
{
    T last = default(T);
    bool gotAny = false;
    foreach (T element in source)
    {
        last = element;
        gotAny = true;
    }
    if (!gotAny)
    {
        throw new InvalidOperationException("Empty list");
    }
    return last;
}

我怀疑Last的实际实现会检查source是否为IList<T>,如果是,则返回list[list.Count-1],以避免必须遍历整个集合。正如评论中指出的那样,这些不是扩展方法 - 你应该这样写:
// Assuming the method is in a CollectionHelpers class.
Foo first = CollectionHelpers.First(list);

替代

Foo first = list.First();

但效果是一样的。


我认为LINQ的First()和Last()比仅仅获取列表中的第一个或最后一个项目更复杂。它们接受一个谓词,用于搜索满足函数的第一个或最后一个项目。例如-您可以传递一个lambda函数来查找第一个唯一项。 - Mel Green
接受谓词的重载确实存在。然而,考虑到 OP 知道 Find 和 FindLast(它们是这些重载的等效项),我认为他实际上对无参数的那些更感兴趣。 - Jon Skeet
扩展方法不是 .NET 3.0 的一部分吗,也就是说不在 VS2005 (.NET 2.0) 中。 - FryGuy
FryGuy:它们是C# 3的一部分,但您仍然可以使用静态方法实现相同的功能,并通过传递参数来调用它们。这只是调用First(list)而不是list.First的情况。 - Jon Skeet

2

这里存在2个问题:

  1. First和Last都是扩展方法。VS2005中包含的编译器不支持扩展方法,因此无法绑定到它们。
  2. First和Last方法包含在3.5框架中,但VS2005无法使用该框架。

1

First 不是 List<T> 的方法。First 是 .net 3.5 中 System.Linq.Enumerable 上的静态方法。


1

这些是扩展方法。你提出了一个典型的反对扩展方法的案例,因为它们似乎属于类,但实际上是在其他地方定义的,所以可能会令人困惑。对于List的第一个/最后一个元素,你仍然可以使用list[0]和list[list.Count-1](当然要添加错误处理)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接