C# 如何从 .net 中的 IEnumerable<T> 获取第一个元素?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/497261/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I get the first element from an IEnumerable<T> in .net?
提问by TimK
I often want to grab the first element of an IEnumerable<T>
in .net, and I haven't found a nice way to do it. The best I've come up with is:
我经常想获取IEnumerable<T>
.net 中的第一个元素,但我还没有找到一个很好的方法来做到这一点。我想出的最好的是:
foreach(Elem e in enumerable) {
// do something with e
break;
}
Yuck! So, is there a nice way to do this?
糟糕!那么,有没有好的方法来做到这一点?
采纳答案by Erik Forbes
If you can use LINQ you can use:
如果您可以使用 LINQ,则可以使用:
var e = enumerable.First();
This will throw an exception though if enumerable is empty: in which case you can use:
如果 enumerable 为空,这将引发异常:在这种情况下,您可以使用:
var e = enumerable.FirstOrDefault();
FirstOrDefault()
will return default(T)
if the enumerable is empty, which will be null
for reference types or the default 'zero-value' for value types.
FirstOrDefault()
default(T)
如果可枚举为空,则返回,这将null
用于引用类型或值类型的默认“零值”。
If you can't use LINQ, then your approach is technically correct and no different than creating an enumerator using the GetEnumerator
and MoveNext
methods to retrieve the first result (this example assumes enumerable is an IEnumerable<Elem>
):
如果您不能使用 LINQ,那么您的方法在技术上是正确的,与使用GetEnumerator
和MoveNext
方法创建枚举器以检索第一个结果没有什么不同(此示例假定可枚举是IEnumerable<Elem>
):
Elem e = myDefault;
using (IEnumerator<Elem> enumer = enumerable.GetEnumerator()) {
if (enumer.MoveNext()) e = enumer.Current;
}
Joel Coehoornmentioned .Single()
in the comments; this will also work, if you are expecting your enumerable to contain exactly one element - however it will throw an exception if it is either empty or larger than one element. There is a corresponding SingleOrDefault()
method that covers this scenario in a similar fashion to FirstOrDefault()
. However, David Bexplains that SingleOrDefault()
may still throw an exception in the case where the enumerable contains more than one item.
.Single()
评论中提到的Joel Coehoorn;如果您希望 enumerable 只包含一个元素,这也将起作用 - 但是,如果它为空或大于一个元素,它将引发异常。有一种相应的SingleOrDefault()
方法可以以与 类似的方式涵盖此场景FirstOrDefault()
。但是,David B解释说,SingleOrDefault()
在可枚举项包含多个项目的情况下,仍可能引发异常。
Edit: Thanks Marc Gravellfor pointing out that I need to dispose of my IEnumerator
object after using it - I've edited the non-LINQ example to display the using
keyword to implement this pattern.
编辑:感谢Marc Gravell指出我需要IEnumerator
在使用后处理我的对象 - 我已经编辑了非 LINQ 示例以显示using
实现此模式的关键字。
回答by Amy B
回答by Adam Lassek
Well, you didn't specify which version of .Net you're using.
好吧,您没有指定您使用的是哪个版本的 .Net。
Assuming you have 3.5, another way is the ElementAt method:
假设您有 3.5,另一种方法是 ElementAt 方法:
var e = enumerable.ElementAt(0);
回答by BenAlabaster
Just in case you're using .NET 2.0 and don't have access to LINQ:
以防万一您使用 .NET 2.0 并且无权访问 LINQ:
static T First<T>(IEnumerable<T> items)
{
using(IEnumerator<T> iter = items.GetEnumerator())
{
iter.MoveNext();
return iter.Current;
}
}
This should do what you're looking for...it uses generics so you to get the first item on any type IEnumerable.
这应该可以满足您的要求...它使用泛型,因此您可以获得任何类型 IEnumerable 上的第一项。
Call it like so:
像这样称呼它:
List<string> items = new List<string>() { "A", "B", "C", "D", "E" };
string firstItem = First<string>(items);
Or
或者
int[] items = new int[] { 1, 2, 3, 4, 5 };
int firstItem = First<int>(items);
You could modify it readily enough to mimic .NET 3.5's IEnumerable.ElementAt() extension method:
你可以很容易地修改它来模仿 .NET 3.5 的 IEnumerable.ElementAt() 扩展方法:
static T ElementAt<T>(IEnumerable<T> items, int index)
{
using(IEnumerator<T> iter = items.GetEnumerator())
{
for (int i = 0; i <= index; i++, iter.MoveNext()) ;
return iter.Current;
}
}
Calling it like so:
像这样调用它:
int[] items = { 1, 2, 3, 4, 5 };
int elemIdx = 3;
int item = ElementAt<int>(items, elemIdx);
Of course if you dohave access to LINQ, then there are plenty of good answers posted already...
当然,如果您确实可以访问 LINQ,那么已经发布了很多好的答案......
回答by Mouk
Use FirstOrDefault or a foreach loop as already mentioned. Manually fetching an enumerator and calling Current should be avoided. foreach will dispose your enumerator for you if it implements IDisposable. When calling MoveNext and Current you have to dispose it manually (if aplicable).
使用 FirstOrDefault 或前面提到的 foreach 循环。应避免手动获取枚举数并调用 Current。如果 foreach 实现了 IDisposable,它将为您处理您的枚举器。调用 MoveNext 和 Current 时,您必须手动处理它(如果适用)。
回答by CZahrobsky
If your IEnumerable doesn't expose it's <T>
and Linq fails, you can write a method using reflection:
如果您的 IEnumerable 没有公开它<T>
并且 Linq 失败,您可以使用反射编写一个方法:
public static T GetEnumeratedItem<T>(Object items, int index) where T : class
{
T item = null;
if (items != null)
{
System.Reflection.MethodInfo mi = items.GetType()
.GetMethod("GetEnumerator");
if (mi != null)
{
object o = mi.Invoke(items, null);
if (o != null)
{
System.Reflection.MethodInfo mn = o.GetType()
.GetMethod("MoveNext");
if (mn != null)
{
object next = mn.Invoke(o, null);
while (next != null && next.ToString() == "True")
{
if (index < 1)
{
System.Reflection.PropertyInfo pi = o
.GetType().GetProperty("Current");
if (pi != null) item = pi
.GetValue(o, null) as T;
break;
}
index--;
}
}
}
}
}
return item;
}
回答by daodao
try this
尝试这个
IEnumberable<string> aa;
string a = (from t in aa where t.Equals("") select t.Value).ToArray()[0];
回答by random person on the internet
you can also try the more generic version which gives you the ith element
您还可以尝试更通用的版本,它为您提供第 i 个元素
enumerable.ElementAtOrDefault(i));
enumerable.ElementAtOrDefault(i));
hope it helps
希望能帮助到你