Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corefx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2017-01-04 02:22:53 +0300
committerGitHub <noreply@github.com>2017-01-04 02:22:53 +0300
commit67414d80dc82f933c9d45beb2d1e9cabac430162 (patch)
tree156d62f5fc77f35bcb5b9e2bcae1191f9dd05c2b /src
parent8dc68d828c1d0478e1390a7d83367b5806894b7d (diff)
parent171b6629e4875fd837308a0cc3f264b4cc6ba99a (diff)
Merge pull request #14537 from jamesqo/more-xml-docs
Add XML docs to some Linq iterators
Diffstat (limited to 'src')
-rw-r--r--src/System.Linq/src/System/Linq/AppendPrepend.cs49
-rw-r--r--src/System.Linq/src/System/Linq/Buffer.cs15
-rw-r--r--src/System.Linq/src/System/Linq/Concat.cs21
-rw-r--r--src/System.Linq/src/System/Linq/Distinct.cs4
-rw-r--r--src/System.Linq/src/System/Linq/Iterator.cs75
-rw-r--r--src/System.Linq/src/System/Linq/Partition.cs69
-rw-r--r--src/System.Linq/src/System/Linq/Range.cs3
-rw-r--r--src/System.Linq/src/System/Linq/Repeat.cs4
-rw-r--r--src/System.Linq/src/System/Linq/Reverse.cs4
-rw-r--r--src/System.Linq/src/System/Linq/Select.cs30
-rw-r--r--src/System.Linq/src/System/Linq/Set.cs89
-rw-r--r--src/System.Linq/src/System/Linq/Union.cs14
-rw-r--r--src/System.Linq/src/System/Linq/Utilities.cs29
-rw-r--r--src/System.Linq/src/System/Linq/Where.cs27
14 files changed, 374 insertions, 59 deletions
diff --git a/src/System.Linq/src/System/Linq/AppendPrepend.cs b/src/System.Linq/src/System/Linq/AppendPrepend.cs
index c5ae31b201..e1cf0cf6c5 100644
--- a/src/System.Linq/src/System/Linq/AppendPrepend.cs
+++ b/src/System.Linq/src/System/Linq/AppendPrepend.cs
@@ -41,6 +41,10 @@ namespace System.Linq
return new AppendPrepend1Iterator<TSource>(source, element, false);
}
+ /// <summary>
+ /// Represents the insertion of one or more items before or after an <see cref="IEnumerable{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerable.</typeparam>
private abstract class AppendPrependIterator<TSource> : Iterator<TSource>, IIListProvider<TSource>
{
protected readonly IEnumerable<TSource> _source;
@@ -92,6 +96,10 @@ namespace System.Linq
public abstract int GetCount(bool onlyIfCheap);
}
+ /// <summary>
+ /// Represents the insertion of an item before or after an <see cref="IEnumerable{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerable.</typeparam>
private class AppendPrepend1Iterator<TSource> : AppendPrependIterator<TSource>
{
private readonly TSource _item;
@@ -260,8 +268,17 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An immutable node in a singly-linked list of items.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the node's item.</typeparam>
private sealed class SingleLinkedNode<TSource>
{
+ /// <summary>
+ /// Constructs a node linked to the tail node.
+ /// </summary>
+ /// <param name="first">The first item, to be placed in the tail node.</param>
+ /// <param name="second">The second item, to be placed in this node.</param>
public SingleLinkedNode(TSource first, TSource second)
{
Linked = new SingleLinkedNode<TSource>(first);
@@ -269,12 +286,21 @@ namespace System.Linq
Count = 2;
}
+ /// <summary>
+ /// Constructs a tail node.
+ /// </summary>
+ /// <param name="item">The item to place in the tail node.</param>
public SingleLinkedNode(TSource item)
{
Item = item;
Count = 1;
}
+ /// <summary>
+ /// Constructs a node linked to the specified node.
+ /// </summary>
+ /// <param name="linked">The linked node.</param>
+ /// <param name="item">The item to place in this node.</param>
private SingleLinkedNode(SingleLinkedNode<TSource> linked, TSource item)
{
Debug.Assert(linked != null);
@@ -283,19 +309,38 @@ namespace System.Linq
Count = linked.Count + 1;
}
+ /// <summary>
+ /// The item held by this node.
+ /// </summary>
public TSource Item { get; }
+ /// <summary>
+ /// The next node in the singly-linked list.
+ /// </summary>
public SingleLinkedNode<TSource> Linked { get; }
+ /// <summary>
+ /// The number of items stored in this and subsequent nodes.
+ /// </summary>
public int Count { get; }
+ /// <summary>
+ /// Creates a new node that holds the specified item and is linked to this node.
+ /// </summary>
+ /// <param name="item">The item to place in the new node.</param>
public SingleLinkedNode<TSource> Add(TSource item) => new SingleLinkedNode<TSource>(this, item);
+ /// <summary>
+ /// Gets an <see cref="IEnumerator{TSource}"/> that enumerates the items of this node's singly-linked list in reverse.
+ /// </summary>
public IEnumerator<TSource> GetEnumerator()
{
return ((IEnumerable<TSource>)ToArray()).GetEnumerator();
}
+ /// <summary>
+ /// Returns an <see cref="T:TSource[]"/> that contains the items of this node's singly-linked list in reverse.
+ /// </summary>
public TSource[] ToArray()
{
TSource[] array = new TSource[Count];
@@ -311,6 +356,10 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// Represents the insertion of multiple items before or after an <see cref="IEnumerable{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerable.</typeparam>
private class AppendPrependN<TSource> : AppendPrependIterator<TSource>
{
private readonly SingleLinkedNode<TSource> _prepended;
diff --git a/src/System.Linq/src/System/Linq/Buffer.cs b/src/System.Linq/src/System/Linq/Buffer.cs
index 839e1450fb..16d5cc1ee4 100644
--- a/src/System.Linq/src/System/Linq/Buffer.cs
+++ b/src/System.Linq/src/System/Linq/Buffer.cs
@@ -6,11 +6,26 @@ using System.Collections.Generic;
namespace System.Linq
{
+ /// <summary>
+ /// A buffer into which the contents of an <see cref="IEnumerable{TElement}"/> can be stored.
+ /// </summary>
+ /// <typeparam name="TElement">The type of the buffer's elements.</typeparam>
internal struct Buffer<TElement>
{
+ /// <summary>
+ /// The stored items.
+ /// </summary>
internal readonly TElement[] _items;
+
+ /// <summary>
+ /// The number of stored items.
+ /// </summary>
internal readonly int _count;
+ /// <summary>
+ /// Fully enumerates the provided enumerable and stores its items into an array.
+ /// </summary>
+ /// <param name="source">The enumerable to be store.</param>
internal Buffer(IEnumerable<TElement> source)
{
IIListProvider<TElement> iterator = source as IIListProvider<TElement>;
diff --git a/src/System.Linq/src/System/Linq/Concat.cs b/src/System.Linq/src/System/Linq/Concat.cs
index aae66235ad..feda438775 100644
--- a/src/System.Linq/src/System/Linq/Concat.cs
+++ b/src/System.Linq/src/System/Linq/Concat.cs
@@ -44,6 +44,10 @@ namespace System.Linq
return new Concat2EnumerableIterator<TSource>(first, second);
}
+ /// <summary>
+ /// Represents the concatenation of two <see cref="IEnumerable{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerables.</typeparam>
private sealed class Concat2EnumerableIterator<TSource> : ConcatIterator<TSource>
{
private readonly IEnumerable<TSource> _first;
@@ -83,6 +87,11 @@ namespace System.Linq
// only have to traverse all of the previous sources once per chained enumerable. An
// alternative would be to use an array to store all of the enumerables, but this has
// a much better memory profile and without much additional run-time cost.
+
+ /// <summary>
+ /// Represents the concatenation of three or more <see cref="IEnumerable{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerables.</typeparam>
private sealed class ConcatNEnumerableIterator<TSource> : ConcatIterator<TSource>
{
private readonly ConcatIterator<TSource> _previousConcat;
@@ -162,6 +171,10 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// Represents the concatenation of two <see cref="ICollection{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source collections.</typeparam>
private sealed class Concat2CollectionIterator<TSource> : ConcatIterator<TSource>
{
private readonly ICollection<TSource> _first;
@@ -232,6 +245,10 @@ namespace System.Linq
public override int GetCount(bool onlyIfCheap) => Count; // Getting the count is always cheap.
}
+ /// <summary>
+ /// Represents the concatenation of three or more <see cref="ICollection{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source collections.</typeparam>
private sealed class ConcatNCollectionIterator<TSource> : ConcatIterator<TSource>
{
private readonly ConcatIterator<TSource> _previous;
@@ -387,6 +404,10 @@ namespace System.Linq
public override int GetCount(bool onlyIfCheap) => Count; // Getting the count is always cheap relative to manually iterating.
}
+ /// <summary>
+ /// Represents the concatenation of two or more <see cref="IEnumerable{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerables.</typeparam>
private abstract class ConcatIterator<TSource> : Iterator<TSource>, IIListProvider<TSource>
{
private IEnumerator<TSource> _enumerator;
diff --git a/src/System.Linq/src/System/Linq/Distinct.cs b/src/System.Linq/src/System/Linq/Distinct.cs
index 054b96b649..65d0a02d6c 100644
--- a/src/System.Linq/src/System/Linq/Distinct.cs
+++ b/src/System.Linq/src/System/Linq/Distinct.cs
@@ -24,6 +24,10 @@ namespace System.Linq
return new DistinctIterator<TSource>(source, comparer);
}
+ /// <summary>
+ /// An iterator that yields the distinct values in an <see cref="IEnumerable{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerable.</typeparam>
private sealed class DistinctIterator<TSource> : Iterator<TSource>, IIListProvider<TSource>
{
private readonly IEnumerable<TSource> _source;
diff --git a/src/System.Linq/src/System/Linq/Iterator.cs b/src/System.Linq/src/System/Linq/Iterator.cs
index 7425046e26..27a15c2e42 100644
--- a/src/System.Linq/src/System/Linq/Iterator.cs
+++ b/src/System.Linq/src/System/Linq/Iterator.cs
@@ -9,30 +9,74 @@ namespace System.Linq
{
public static partial class Enumerable
{
+ /// <summary>
+ /// A base class for enumerables that are loaded on-demand.
+ /// </summary>
+ /// <typeparam name="TSource">The type of each item to yield.</typeparam>
+ /// <remarks>
+ /// <list type="bullet">
+ /// <item><description>
+ /// The value of an iterator is immutable; the operation it represents cannot be changed.
+ /// </description></item>
+ /// <item><description>
+ /// However, an iterator also serves as its own enumerator, so the state of an iterator
+ /// may change as it is being enumerated.
+ /// </description></item>
+ /// <item><description>
+ /// Hence, state that is relevant to an iterator's value should be kept in readonly fields.
+ /// State that is relevant to an iterator's enumeration (such as the currently yielded item)
+ /// should be kept in non-readonly fields.
+ /// </description></item>
+ /// </list>
+ /// </remarks>
internal abstract class Iterator<TSource> : IEnumerable<TSource>, IEnumerator<TSource>
{
private readonly int _threadId;
internal int _state;
internal TSource _current;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Iterator{TSource}"/> class.
+ /// </summary>
protected Iterator()
{
_threadId = Environment.CurrentManagedThreadId;
}
- public TSource Current
- {
- get { return _current; }
- }
+ /// <summary>
+ /// The item currently yielded by this iterator.
+ /// </summary>
+ public TSource Current => _current;
+ /// <summary>
+ /// Makes a shallow copy of this iterator.
+ /// </summary>
+ /// <remarks>
+ /// This method is called if <see cref="GetEnumerator"/> is called more than once.
+ /// </remarks>
public abstract Iterator<TSource> Clone();
+ /// <summary>
+ /// Puts this iterator in a state whereby no further enumeration will take place.
+ /// </summary>
+ /// <remarks>
+ /// Derived classes should override this method if necessary to clean up any
+ /// mutable state they hold onto (for example, calling Dispose on other enumerators).
+ /// </remarks>
public virtual void Dispose()
{
_current = default(TSource);
_state = -1;
}
+ /// <summary>
+ /// Gets the enumerator used to yield values from this iterator.
+ /// </summary>
+ /// <remarks>
+ /// If <see cref="GetEnumerator"/> is called for the first time on the same thread
+ /// that created this iterator, the result will be this iterator. Otherwise, the result
+ /// will be a shallow copy of this iterator.
+ /// </remarks>
public IEnumerator<TSource> GetEnumerator()
{
Iterator<TSource> enumerator = _state == 0 && _threadId == Environment.CurrentManagedThreadId ? this : Clone();
@@ -40,27 +84,34 @@ namespace System.Linq
return enumerator;
}
+ /// <summary>
+ /// Retrieves the next item in this iterator and yields it via <see cref="Current"/>.
+ /// </summary>
+ /// <returns><c>true</c> if there was another value to be yielded; otherwise, <c>false</c>.</returns>
public abstract bool MoveNext();
+ /// <summary>
+ /// Returns an enumerable that maps each item in this iterator based on a selector.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the mapped items.</typeparam>
+ /// <param name="selector">The selector used to map each item.</param>
public virtual IEnumerable<TResult> Select<TResult>(Func<TSource, TResult> selector)
{
return new SelectEnumerableIterator<TSource, TResult>(this, selector);
}
+ /// <summary>
+ /// Returns an enumerable that filters each item in this iterator based on a predicate.
+ /// </summary>
+ /// <param name="predicate">The predicate used to filter each item.</param>
public virtual IEnumerable<TSource> Where(Func<TSource, bool> predicate)
{
return new WhereEnumerableIterator<TSource>(this, predicate);
}
- object IEnumerator.Current
- {
- get { return Current; }
- }
+ object IEnumerator.Current => Current;
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
void IEnumerator.Reset()
{
diff --git a/src/System.Linq/src/System/Linq/Partition.cs b/src/System.Linq/src/System/Linq/Partition.cs
index e16af13ad2..2013018a3e 100644
--- a/src/System.Linq/src/System/Linq/Partition.cs
+++ b/src/System.Linq/src/System/Linq/Partition.cs
@@ -77,40 +77,36 @@ namespace System.Linq
TElement TryGetLast(out bool found);
}
+ /// <summary>
+ /// Represents an enumerable with zero elements.
+ /// </summary>
+ /// <typeparam name="TElement">The element type.</typeparam>
+ /// <remarks>
+ /// Returning an instance of this type is useful to quickly handle scenarios where it is known
+ /// that an operation will result in zero elements.
+ /// </remarks>
internal sealed class EmptyPartition<TElement> : IPartition<TElement>, IEnumerator<TElement>
{
+ /// <summary>
+ /// A cached, immutable instance of an empty enumerable.
+ /// </summary>
public static readonly IPartition<TElement> Instance = new EmptyPartition<TElement>();
private EmptyPartition()
{
}
- public IEnumerator<TElement> GetEnumerator()
- {
- return this;
- }
+ public IEnumerator<TElement> GetEnumerator() => this;
- IEnumerator IEnumerable.GetEnumerator()
- {
- return this;
- }
+ IEnumerator IEnumerable.GetEnumerator() => this;
- public bool MoveNext()
- {
- return false;
- }
+ public bool MoveNext() => false;
[ExcludeFromCodeCoverage] // Shouldn't be called, and as undefined can return or throw anything anyway.
- public TElement Current
- {
- get { return default(TElement); }
- }
+ public TElement Current => default(TElement);
[ExcludeFromCodeCoverage] // Shouldn't be called, and as undefined can return or throw anything anyway.
- object IEnumerator.Current
- {
- get { return default(TElement); }
- }
+ object IEnumerator.Current => default(TElement);
void IEnumerator.Reset()
{
@@ -122,15 +118,9 @@ namespace System.Linq
// Do nothing.
}
- public IPartition<TElement> Skip(int count)
- {
- return this;
- }
+ public IPartition<TElement> Skip(int count) => this;
- public IPartition<TElement> Take(int count)
- {
- return this;
- }
+ public IPartition<TElement> Take(int count) => this;
public TElement TryGetElementAt(int index, out bool found)
{
@@ -150,20 +140,11 @@ namespace System.Linq
return default(TElement);
}
- public TElement[] ToArray()
- {
- return Array.Empty<TElement>();
- }
+ public TElement[] ToArray() => Array.Empty<TElement>();
- public List<TElement> ToList()
- {
- return new List<TElement>();
- }
+ public List<TElement> ToList() => new List<TElement>();
- public int GetCount(bool onlyIfCheap)
- {
- return 0;
- }
+ public int GetCount(bool onlyIfCheap) => 0;
}
internal sealed class OrderedPartition<TElement> : IPartition<TElement>
@@ -245,6 +226,10 @@ namespace System.Linq
public static partial class Enumerable
{
+ /// <summary>
+ /// An iterator that yields the items of part of an <see cref="IList{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source list.</typeparam>
private sealed class ListPartition<TSource> : Iterator<TSource>, IPartition<TSource>
{
private readonly IList<TSource> _source;
@@ -390,6 +375,10 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An iterator that yields the items of part of an <see cref="IEnumerable{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerable.</typeparam>
private sealed class EnumerablePartition<TSource> : Iterator<TSource>, IPartition<TSource>
{
private readonly IEnumerable<TSource> _source;
diff --git a/src/System.Linq/src/System/Linq/Range.cs b/src/System.Linq/src/System/Linq/Range.cs
index 603e971385..2f5ecbac3a 100644
--- a/src/System.Linq/src/System/Linq/Range.cs
+++ b/src/System.Linq/src/System/Linq/Range.cs
@@ -25,6 +25,9 @@ namespace System.Linq
return new RangeIterator(start, count);
}
+ /// <summary>
+ /// An iterator that yields a range of consecutive integers.
+ /// </summary>
private sealed class RangeIterator : Iterator<int>, IPartition<int>
{
private readonly int _start;
diff --git a/src/System.Linq/src/System/Linq/Repeat.cs b/src/System.Linq/src/System/Linq/Repeat.cs
index e2535f3986..e3fe9c0f72 100644
--- a/src/System.Linq/src/System/Linq/Repeat.cs
+++ b/src/System.Linq/src/System/Linq/Repeat.cs
@@ -24,6 +24,10 @@ namespace System.Linq
return new RepeatIterator<TResult>(element, count);
}
+ /// <summary>
+ /// An iterator that yields the same item multiple times.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the item.</typeparam>
private sealed class RepeatIterator<TResult> : Iterator<TResult>, IPartition<TResult>
{
private readonly int _count;
diff --git a/src/System.Linq/src/System/Linq/Reverse.cs b/src/System.Linq/src/System/Linq/Reverse.cs
index 81edc65ae0..594eb89a77 100644
--- a/src/System.Linq/src/System/Linq/Reverse.cs
+++ b/src/System.Linq/src/System/Linq/Reverse.cs
@@ -20,6 +20,10 @@ namespace System.Linq
return new ReverseIterator<TSource>(source);
}
+ /// <summary>
+ /// An iterator that yields the items of an <see cref="IEnumerable{TSource}"/> in reverse.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerable.</typeparam>
private sealed class ReverseIterator<TSource> : Iterator<TSource>, IIListProvider<TSource>
{
private readonly IEnumerable<TSource> _source;
diff --git a/src/System.Linq/src/System/Linq/Select.cs b/src/System.Linq/src/System/Linq/Select.cs
index 006a0c7688..3e7331982d 100644
--- a/src/System.Linq/src/System/Linq/Select.cs
+++ b/src/System.Linq/src/System/Linq/Select.cs
@@ -86,6 +86,11 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An iterator that maps each item of an <see cref="IEnumerable{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerable.</typeparam>
+ /// <typeparam name="TResult">The type of the mapped items.</typeparam>
internal sealed class SelectEnumerableIterator<TSource, TResult> : Iterator<TResult>, IIListProvider<TResult>
{
private readonly IEnumerable<TSource> _source;
@@ -192,6 +197,11 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An iterator that maps each item of a <see cref="T:TSource[]"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source array.</typeparam>
+ /// <typeparam name="TResult">The type of the mapped items.</typeparam>
internal sealed class SelectArrayIterator<TSource, TResult> : Iterator<TResult>, IPartition<TResult>
{
private readonly TSource[] _source;
@@ -317,6 +327,11 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An iterator that maps each item of a <see cref="List{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source list.</typeparam>
+ /// <typeparam name="TResult">The type of the mapped items.</typeparam>
internal sealed class SelectListIterator<TSource, TResult> : Iterator<TResult>, IPartition<TResult>
{
private readonly List<TSource> _source;
@@ -459,6 +474,11 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An iterator that maps each item of an <see cref="IList{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source list.</typeparam>
+ /// <typeparam name="TResult">The type of the mapped items.</typeparam>
internal sealed class SelectIListIterator<TSource, TResult> : Iterator<TResult>, IPartition<TResult>
{
private readonly IList<TSource> _source;
@@ -612,6 +632,11 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An iterator that maps each item of an <see cref="IPartition{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source partition.</typeparam>
+ /// <typeparam name="TResult">The type of the mapped items.</typeparam>
internal sealed class SelectIPartitionIterator<TSource, TResult> : Iterator<TResult>, IPartition<TResult>
{
private readonly IPartition<TSource> _source;
@@ -787,6 +812,11 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An iterator that maps each item of part of an <see cref="IList{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source list.</typeparam>
+ /// <typeparam name="TResult">The type of the mapped items.</typeparam>
private sealed class SelectListPartitionIterator<TSource, TResult> : Iterator<TResult>, IPartition<TResult>
{
private readonly IList<TSource> _source;
diff --git a/src/System.Linq/src/System/Linq/Set.cs b/src/System.Linq/src/System/Linq/Set.cs
index 60bf491b30..ac0c0afdd5 100644
--- a/src/System.Linq/src/System/Linq/Set.cs
+++ b/src/System.Linq/src/System/Linq/Set.cs
@@ -7,16 +7,51 @@ using System.Diagnostics;
namespace System.Linq
{
+ /// <summary>
+ /// A lightweight hash set.
+ /// </summary>
+ /// <typeparam name="TElement">The type of the set's items.</typeparam>
internal sealed class Set<TElement>
{
+ /// <summary>
+ /// The comparer used to hash and compare items in the set.
+ /// </summary>
private readonly IEqualityComparer<TElement> _comparer;
+
+ /// <summary>
+ /// The hash buckets, which are used to index into the slots.
+ /// </summary>
private int[] _buckets;
+
+ /// <summary>
+ /// The slots, each of which store an item and its hash code.
+ /// </summary>
private Slot[] _slots;
+
+ /// <summary>
+ /// The number of items in this set.
+ /// </summary>
private int _count;
+
#if DEBUG
+ /// <summary>
+ /// Whether <see cref="Remove"/> has been called on this set.
+ /// </summary>
+ /// <remarks>
+ /// When <see cref="Remove"/> runs in debug builds, this flag is set to <c>true</c>.
+ /// Other methods assert that this flag is <c>false</c> in debug builds, because
+ /// they make optimizations that may not be correct if <see cref="Remove"/> is called
+ /// beforehand.
+ /// </remarks>
private bool _haveRemoved;
#endif
+ /// <summary>
+ /// Constructs a set that compares items with the specified comparer.
+ /// </summary>
+ /// <param name="comparer">
+ /// The comparer. If this is <c>null</c>, it defaults to <see cref="EqualityComparer{TElement}.Default"/>.
+ /// </param>
public Set(IEqualityComparer<TElement> comparer)
{
_comparer = comparer ?? EqualityComparer<TElement>.Default;
@@ -24,7 +59,13 @@ namespace System.Linq
_slots = new Slot[7];
}
- // If value is not in set, add it and return true; otherwise return false
+ /// <summary>
+ /// Attempts to add an item to this set.
+ /// </summary>
+ /// <param name="value">The item to add.</param>
+ /// <returns>
+ /// <c>true</c> if the item was not in the set; otherwise, <c>false</c>.
+ /// </returns>
public bool Add(TElement value)
{
#if DEBUG
@@ -54,7 +95,13 @@ namespace System.Linq
return true;
}
- // If value is in set, remove it and return true; otherwise return false
+ /// <summary>
+ /// Attempts to remove an item from this set.
+ /// </summary>
+ /// <param name="value">The item to remove.</param>
+ /// <returns>
+ /// <c>true</c> if the item was in the set; otherwise, <c>false</c>.
+ /// </returns>
public bool Remove(TElement value)
{
#if DEBUG
@@ -86,6 +133,9 @@ namespace System.Linq
return false;
}
+ /// <summary>
+ /// Expands the capacity of this set to double the current capacity, plus one.
+ /// </summary>
private void Resize()
{
int newSize = checked((_count * 2) + 1);
@@ -103,6 +153,10 @@ namespace System.Linq
_slots = newSlots;
}
+ /// <summary>
+ /// Creates an array from the items in this set.
+ /// </summary>
+ /// <returns>An array of the items in this set.</returns>
internal TElement[] ToArray()
{
#if DEBUG
@@ -117,6 +171,10 @@ namespace System.Linq
return array;
}
+ /// <summary>
+ /// Creates a list from the items in this set.
+ /// </summary>
+ /// <returns>A list of the items in this set.</returns>
internal List<TElement> ToList()
{
#if DEBUG
@@ -132,21 +190,40 @@ namespace System.Linq
return list;
}
- internal int Count
- {
- get { return _count; }
- }
+ /// <summary>
+ /// The number of items in this set.
+ /// </summary>
+ internal int Count => _count;
+ /// <summary>
+ /// Gets the hash code of the provided value with its sign bit zeroed out, so that modulo has a positive result.
+ /// </summary>
+ /// <param name="value">The value to hash.</param>
+ /// <returns>The lower 31 bits of the value's hash code.</returns>
internal int InternalGetHashCode(TElement value)
{
// Handle comparer implementations that throw when passed null
return (value == null) ? 0 : _comparer.GetHashCode(value) & 0x7FFFFFFF;
}
+ /// <summary>
+ /// An entry in the hash set.
+ /// </summary>
internal struct Slot
{
+ /// <summary>
+ /// The hash code of the item.
+ /// </summary>
internal int _hashCode;
+
+ /// <summary>
+ /// In the case of a hash collision, the index of the next slot to probe.
+ /// </summary>
internal int _next;
+
+ /// <summary>
+ /// The item held by this slot.
+ /// </summary>
internal TElement _value;
}
}
diff --git a/src/System.Linq/src/System/Linq/Union.cs b/src/System.Linq/src/System/Linq/Union.cs
index 97c79f701d..431928d3c3 100644
--- a/src/System.Linq/src/System/Linq/Union.cs
+++ b/src/System.Linq/src/System/Linq/Union.cs
@@ -31,6 +31,10 @@ namespace System.Linq
return union != null && AreEqualityComparersEqual(comparer, union._comparer) ? union.Union(second) : new UnionIterator2<TSource>(first, second, comparer);
}
+ /// <summary>
+ /// An iterator that yields distinct values from two or more <see cref="IEnumerable{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerables.</typeparam>
private abstract class UnionIterator<TSource> : Iterator<TSource>, IIListProvider<TSource>
{
internal readonly IEqualityComparer<TSource> _comparer;
@@ -166,7 +170,11 @@ namespace System.Linq
return onlyIfCheap ? -1 : FillSet().Count;
}
}
-
+
+ /// <summary>
+ /// An iterator that yields distinct values from two <see cref="IEnumerable{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerables.</typeparam>
private sealed class UnionIterator2<TSource> : UnionIterator<TSource>
{
private readonly IEnumerable<TSource> _first;
@@ -206,6 +214,10 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An iterator that yields distinct values from three or more <see cref="IEnumerable{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerables.</typeparam>
private sealed class UnionIteratorN<TSource> : UnionIterator<TSource>
{
private readonly UnionIterator<TSource> _previous;
diff --git a/src/System.Linq/src/System/Linq/Utilities.cs b/src/System.Linq/src/System/Linq/Utilities.cs
index 9dd80d917f..7c226f0a52 100644
--- a/src/System.Linq/src/System/Linq/Utilities.cs
+++ b/src/System.Linq/src/System/Linq/Utilities.cs
@@ -11,6 +11,13 @@ namespace System.Linq
/// </summary>
internal static class Utilities
{
+ /// <summary>
+ /// Decides if two equality comparers are equivalent.
+ /// </summary>
+ /// <typeparam name="TSource">The type of each comparer.</typeparam>
+ /// <param name="left">The first comparer.</param>
+ /// <param name="right">The second comparer.</param>
+ /// <returns><c>true</c> if the equality comparers are equal; otherwise, <c>false</c>.</returns>
public static bool AreEqualityComparersEqual<TSource>(IEqualityComparer<TSource> left, IEqualityComparer<TSource> right)
{
if (left == right)
@@ -36,11 +43,33 @@ namespace System.Linq
return left.Equals(right);
}
+ /// <summary>
+ /// Combines two predicates.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the predicate argument.</typeparam>
+ /// <param name="predicate1">The first predicate to run.</param>
+ /// <param name="predicate2">The second predicate to run.</param>
+ /// <returns>
+ /// A new predicate that will evaluate to <c>true</c> only if both the first and
+ /// second predicates return true. If the first predicate returns <c>false</c>,
+ /// the second predicate will not be run.
+ /// </returns>
public static Func<TSource, bool> CombinePredicates<TSource>(Func<TSource, bool> predicate1, Func<TSource, bool> predicate2)
{
return x => predicate1(x) && predicate2(x);
}
+ /// <summary>
+ /// Combines two selectors.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the first selector's argument.</typeparam>
+ /// <typeparam name="TMiddle">The type of the second selector's argument.</typeparam>
+ /// <typeparam name="TResult">The type of the second selector's return value.</typeparam>
+ /// <param name="selector1">The first selector to run.</param>
+ /// <param name="selector2">The second selector to run.</param>
+ /// <returns>
+ /// A new selector that represents the composition of the first selector with the second selector.
+ /// </returns>
public static Func<TSource, TResult> CombineSelectors<TSource, TMiddle, TResult>(Func<TSource, TMiddle> selector1, Func<TMiddle, TResult> selector2)
{
return x => selector2(selector1(x));
diff --git a/src/System.Linq/src/System/Linq/Where.cs b/src/System.Linq/src/System/Linq/Where.cs
index 823ab0157b..d2f8e42d5b 100644
--- a/src/System.Linq/src/System/Linq/Where.cs
+++ b/src/System.Linq/src/System/Linq/Where.cs
@@ -77,6 +77,10 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An iterator that filters each item of an <see cref="IEnumerable{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerable.</typeparam>
internal sealed class WhereEnumerableIterator<TSource> : Iterator<TSource>, IIListProvider<TSource>
{
private readonly IEnumerable<TSource> _source;
@@ -197,6 +201,10 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An iterator that filters each item of a <see cref="T:TSource[]"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source array.</typeparam>
internal sealed class WhereArrayIterator<TSource> : Iterator<TSource>, IIListProvider<TSource>
{
private readonly TSource[] _source;
@@ -299,6 +307,10 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An iterator that filters each item of a <see cref="List{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source list.</typeparam>
internal sealed class WhereListIterator<TSource> : Iterator<TSource>, IIListProvider<TSource>
{
private readonly List<TSource> _source;
@@ -411,6 +423,11 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An iterator that filters, then maps, each item of a <see cref="T:TSource[]"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source array.</typeparam>
+ /// <typeparam name="TResult">The type of the mapped items.</typeparam>
internal sealed class WhereSelectArrayIterator<TSource, TResult> : Iterator<TResult>, IIListProvider<TResult>
{
private readonly TSource[] _source;
@@ -515,6 +532,11 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An iterator that filters, then maps, each item of a <see cref="List{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source list.</typeparam>
+ /// <typeparam name="TResult">The type of the mapped items.</typeparam>
internal sealed class WhereSelectListIterator<TSource, TResult> : Iterator<TResult>, IIListProvider<TResult>
{
private readonly List<TSource> _source;
@@ -629,6 +651,11 @@ namespace System.Linq
}
}
+ /// <summary>
+ /// An iterator that filters, then maps, each item of an <see cref="IEnumerable{TSource}"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the source enumerable.</typeparam>
+ /// <typeparam name="TResult">The type of the mapped items.</typeparam>
internal sealed class WhereSelectEnumerableIterator<TSource, TResult> : Iterator<TResult>, IIListProvider<TResult>
{
private readonly IEnumerable<TSource> _source;