Skip to content
Permalink
master
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time
162 lines (143 sloc) 4.76 KB
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace System.Linq
{
public static partial class Enumerable
{
public static TSource Single<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
}
if (source is IList<TSource> list)
{
switch (list.Count)
{
case 0:
ThrowHelper.ThrowNoElementsException();
return default;
case 1:
return list[0];
}
}
else
{
using (IEnumerator<TSource> e = source.GetEnumerator())
{
if (!e.MoveNext())
{
ThrowHelper.ThrowNoElementsException();
}
TSource result = e.Current;
if (!e.MoveNext())
{
return result;
}
}
}
ThrowHelper.ThrowMoreThanOneElementException();
return default;
}
public static TSource Single<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
}
if (predicate == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.predicate);
}
using (IEnumerator<TSource> e = source.GetEnumerator())
{
while (e.MoveNext())
{
TSource result = e.Current;
if (predicate(result))
{
while (e.MoveNext())
{
if (predicate(e.Current))
{
ThrowHelper.ThrowMoreThanOneMatchException();
}
}
return result;
}
}
}
ThrowHelper.ThrowNoMatchException();
return default;
}
[return: MaybeNull]
public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
}
if (source is IList<TSource> list)
{
switch (list.Count)
{
case 0:
return default!;
case 1:
return list[0];
}
}
else
{
using (IEnumerator<TSource> e = source.GetEnumerator())
{
if (!e.MoveNext())
{
return default!;
}
TSource result = e.Current;
if (!e.MoveNext())
{
return result;
}
}
}
ThrowHelper.ThrowMoreThanOneElementException();
return default;
}
[return: MaybeNull]
public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
}
if (predicate == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.predicate);
}
using (IEnumerator<TSource> e = source.GetEnumerator())
{
while (e.MoveNext())
{
TSource result = e.Current;
if (predicate(result))
{
while (e.MoveNext())
{
if (predicate(e.Current))
{
ThrowHelper.ThrowMoreThanOneMatchException();
}
}
return result;
}
}
}
return default!;
}
}
}