这两条线有什么明显的区别吗?
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 不等,具体取决于它是什么模式。所以文件数量很多。
最佳答案
检查来源。 ElementAt
和 First
都是在 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/