我想要像length != 1
这样的内容,但我希望v.Count() == 1 ? v[0] : default
返回默认值。像{{1}}这样的东西。但我更愿意在不将整个枚举转换为数组的情况下完成它。获得这种行为的最佳方法是什么?
答案 0 :(得分:9)
Microsoft的Enumerable.FirstOrDefault实现直接与底层枚举器一起工作。你也可以:
public static T FirstIfOnlyOne<T>(this IEnumerable<T> source, T defaultValue = default(T))
{
// (Null check and IList<T> optimization omitted...)
using (IEnumerator<T> enumerator = source.GetEnumerator())
{
if (enumerator.MoveNext()) // Is there at least one item?
{
T item = enumerator.Current; // Save it.
if (!enumerator.MoveNext()) // Is that it?
return item;
}
}
return defaultValue;
}
这可能是最有效的实施方式。
答案 1 :(得分:7)
最好避免多次迭代枚举,因为并非所有枚举都重复相同的值。
为了确保您的枚举只返回1个元素,从枚举中获取前两个元素并将结果转换为数组是最有效的。如果数组有两个元素,你知道可枚举有多个元素而不迭代整个可枚举。可枚举可能无限长。
所以这是如何做到的:
public static T OneOnlyThenFirstOrDefault<T>(this IEnumerable<T> source)
{
var beginning = source.Take(2).ToArray();
return beginning.Length == 1 ? beginning[0] : default(T);
}
答案 2 :(得分:0)
您是否尝试过编写自定义扩展方法,例如:
public static TSource MyFirstOrDefault<TSource>(this IEnumerable<TSource> source)
{
return source.Count() == 1 ? source.First() : default(TSource);
}
但是你需要记住,方法Count()
和First()
需要实例化内部元素集合才能获得计数(或第一个元素)。
希望,这对你有帮助。