c# - 使用 LINQ 获取 IEnumerable<T> 中的第一个(也是唯一一个)元素有什么好处吗?

标签 c# linq

这两条线有什么明显的区别吗?

var o = xmlFile.Descendants("SomeElement").ElementAt(0).Value;

和:

var o = xmlFile.Descendants("SomeElement").First().Value;

XmlFile是一个 XDocument对象,和 Descendants(XName name)返回 IEnumerable<XElement> .

我知道First();如果集合为空,将抛出异常,您可能想使用 FirstOrDefault();但在这种情况下没关系;我已经验证了我的 XDocument针对 XmlSchemaSet 的对象,所以我知道该元素存在。我想直接访问 Value如果集合为空,无论哪种方式都会抛出异常,如 ElementAt(0)也不会返回任何东西。

但是是的;显然,我不喜欢添加 using指令,如果我不需要。在这种情况下,有什么理由要使用 LINQ 吗?我无法想象在这两种情况下会有任何真正的性能差异。

我问是因为用户能够上传包含任意数量需要处理的 XML 文件的 zip 文件。每个 XML 文件 1 个“记录”。

编辑:我最初的问题是“如何在不添加 using System.Linq; 的情况下从 IEnumerable 获取第一个元素,然后我找到了 ElementAt ,但没有意识到它们都是一部分LINQ 的。

所以我想我真正想知道的是,上面的任何一个片段和这个片段之间会有区别吗:

var descendants = xmlFile.Descendants("SomeElement");
var enumerator = descendants.GetEnumerator();
var node = (enumerator.MoveNext()) ? enumerator.Current : null;

我肯定会说 LINQ 更具可读性,仅此一点就值得使用。但同样,用户最多可以上传一个 10 MB 的 zip 文件,每个 XML 文件的大小从 2 KB 到 10 KB 不等,具体取决于它是什么模式。所以文件数量很多。

最佳答案

检查来源。 ElementAtFirst 都是在 System.Linq.Enumerable 上定义的扩展方法(如问题评论中的 Lee 所述)。

更新

我也包含了 Single 的实现,正如所讨论的那样,它是解决这个特定问题的更好选择。从根本上说,这归结为可读性和抛出的异常,因为它们都使用相同的方式访问第一个元素。

    public static TSource First<TSource>(this IEnumerable<TSource> source) {
        if (source == null) throw Error.ArgumentNull("source");
        IList<TSource> list = source as IList<TSource>;
        if (list != null) {
            if (list.Count > 0) return list[0];
        }
        else {
            using (IEnumerator<TSource> e = source.GetEnumerator()) {
                if (e.MoveNext()) return e.Current;
            }
        }
        throw Error.NoElements();
    }


    public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index) {
        if (source == null) throw Error.ArgumentNull("source");
        IList<TSource> list = source as IList<TSource>;
        if(list != null) return list[index];
        if (index < 0) throw Error.ArgumentOutOfRange("index");
        using (IEnumerator<TSource> e = source.GetEnumerator()) {
            while (true) {
                if (!e.MoveNext()) throw Error.ArgumentOutOfRange("index");
                if (index == 0) return e.Current;
                index--;
            }
        }
    }

    public static TSource Single<TSource>(this IEnumerable<TSource> source) {
        if (source == null) throw Error.ArgumentNull("source");
        IList<TSource> list = source as IList<TSource>;
        if (list != null) {
            switch (list.Count) {
                case 0: throw Error.NoElements();
                case 1: return list[0];
            }
        }
        else {
            using (IEnumerator<TSource> e = source.GetEnumerator()) {
                if (!e.MoveNext()) throw Error.NoElements();
                TSource result = e.Current;
                if (!e.MoveNext()) return result;
            }
        }
        throw Error.MoreThanOneElement();
    }

关于c# - 使用 LINQ 获取 IEnumerable<T> 中的第一个(也是唯一一个)元素有什么好处吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36915987/

相关文章:

c# - 如何使用 linq 初始化重复元素数组?

c# - 形成两个列表并集的最简单方法

C#根据另一个列表(不同类)的值序列对列表进行排序

c# - C# 对象在不可访问时是否从内存中删除

c# - 为什么必须在三元表达式中强制转换int类型?

c# - MemoryFailPoint 在 WinXP 64 早期触发

C# LINQ - 在 IList 初始值设定项中迭代多个集合

c# - Web API 中的 LINQ 时间减法

c# - 如何将 PDF 文件转换为图像

c# - 如何组合多个 Func<> 委托(delegate)