C#Stack源码
2023-07-27 本文已影响0人
好怕怕
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace System.Collections.Generic
{
/// <summary>Represents a variable size last-in-first-out (LIFO) collection of instances of the same specified type.</summary>
/// <typeparam name="T">Specifies the type of elements in the stack.</typeparam>
// Token: 0x020003C6 RID: 966
[DebuggerTypeProxy(typeof(System_StackDebugView<>))]
[DebuggerDisplay("Count = {Count}")]
[ComVisible(false)]
[__DynamicallyInvokable]
[Serializable]
public class Stack<T> : IEnumerable<T>, IEnumerable, ICollection, IReadOnlyCollection<T>
{
/// <summary>Initializes a new instance of the <see cref="T:System.Collections.Generic.Stack`1" /> class that is empty and has the default initial capacity.</summary>
// Token: 0x0600248F RID: 9359 RVA: 0x000AA8EF File Offset: 0x000A8AEF
[__DynamicallyInvokable]
public Stack()
{
this._array = Stack<T>._emptyArray;
this._size = 0;
this._version = 0;
}
/// <summary>Initializes a new instance of the <see cref="T:System.Collections.Generic.Stack`1" /> class that is empty and has the specified initial capacity or the default initial capacity, whichever is greater.</summary>
/// <param name="capacity">The initial number of elements that the <see cref="T:System.Collections.Generic.Stack`1" /> can contain.</param>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="capacity" /> is less than zero.</exception>
// Token: 0x06002490 RID: 9360 RVA: 0x000AA910 File Offset: 0x000A8B10
[__DynamicallyInvokable]
public Stack(int capacity)
{
if (capacity < 0)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNumRequired);
}
this._array = new T[capacity];
this._size = 0;
this._version = 0;
}
/// <summary>Initializes a new instance of the <see cref="T:System.Collections.Generic.Stack`1" /> class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied.</summary>
/// <param name="collection">The collection to copy elements from.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="collection" /> is <see langword="null" />.</exception>
// Token: 0x06002491 RID: 9361 RVA: 0x000AA940 File Offset: 0x000A8B40
[__DynamicallyInvokable]
public Stack(IEnumerable<T> collection)
{
if (collection == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
ICollection<T> collection2 = collection as ICollection<T>;
if (collection2 != null)
{
int count = collection2.Count;
this._array = new T[count];
collection2.CopyTo(this._array, 0);
this._size = count;
return;
}
this._size = 0;
this._array = new T[4];
foreach (T item in collection)
{
this.Push(item);
}
}
/// <summary>Gets the number of elements contained in the <see cref="T:System.Collections.Generic.Stack`1" />.</summary>
/// <returns>The number of elements contained in the <see cref="T:System.Collections.Generic.Stack`1" />.</returns>
// Token: 0x17000937 RID: 2359
// (get) Token: 0x06002492 RID: 9362 RVA: 0x000AA9DC File Offset: 0x000A8BDC
[__DynamicallyInvokable]
public int Count
{
[__DynamicallyInvokable]
get
{
return this._size;
}
}
/// <summary>Gets a value indicating whether access to the <see cref="T:System.Collections.ICollection" /> is synchronized (thread safe).</summary>
/// <returns>
/// <see langword="true" /> if access to the <see cref="T:System.Collections.ICollection" /> is synchronized (thread safe); otherwise, <see langword="false" />. In the default implementation of <see cref="T:System.Collections.Generic.Stack`1" />, this property always returns <see langword="false" />.</returns>
// Token: 0x17000938 RID: 2360
// (get) Token: 0x06002493 RID: 9363 RVA: 0x000AA9E4 File Offset: 0x000A8BE4
[__DynamicallyInvokable]
bool ICollection.IsSynchronized
{
[__DynamicallyInvokable]
get
{
return false;
}
}
/// <summary>Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection" />.</summary>
/// <returns>An object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection" />. In the default implementation of <see cref="T:System.Collections.Generic.Stack`1" />, this property always returns the current instance.</returns>
// Token: 0x17000939 RID: 2361
// (get) Token: 0x06002494 RID: 9364 RVA: 0x000AA9E7 File Offset: 0x000A8BE7
[__DynamicallyInvokable]
object ICollection.SyncRoot
{
[__DynamicallyInvokable]
get
{
if (this._syncRoot == null)
{
Interlocked.CompareExchange<object>(ref this._syncRoot, new object(), null);
}
return this._syncRoot;
}
}
/// <summary>Removes all objects from the <see cref="T:System.Collections.Generic.Stack`1" />.</summary>
// Token: 0x06002495 RID: 9365 RVA: 0x000AAA09 File Offset: 0x000A8C09
[__DynamicallyInvokable]
public void Clear()
{
Array.Clear(this._array, 0, this._size);
this._size = 0;
this._version++;
}
/// <summary>Determines whether an element is in the <see cref="T:System.Collections.Generic.Stack`1" />.</summary>
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.Stack`1" />. The value can be <see langword="null" /> for reference types.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="item" /> is found in the <see cref="T:System.Collections.Generic.Stack`1" />; otherwise, <see langword="false" />.</returns>
// Token: 0x06002496 RID: 9366 RVA: 0x000AAA34 File Offset: 0x000A8C34
[__DynamicallyInvokable]
public bool Contains(T item)
{
int size = this._size;
EqualityComparer<T> @default = EqualityComparer<T>.Default;
while (size-- > 0)
{
if (item == null)
{
if (this._array[size] == null)
{
return true;
}
}
else if (this._array[size] != null && @default.Equals(this._array[size], item))
{
return true;
}
}
return false;
}
/// <summary>Copies the <see cref="T:System.Collections.Generic.Stack`1" /> to an existing one-dimensional <see cref="T:System.Array" />, starting at the specified array index.</summary>
/// <param name="array">The one-dimensional <see cref="T:System.Array" /> that is the destination of the elements copied from <see cref="T:System.Collections.Generic.Stack`1" />. The <see cref="T:System.Array" /> must have zero-based indexing.</param>
/// <param name="arrayIndex">The zero-based index in <paramref name="array" /> at which copying begins.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="array" /> is <see langword="null" />.</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="arrayIndex" /> is less than zero.</exception>
/// <exception cref="T:System.ArgumentException">The number of elements in the source <see cref="T:System.Collections.Generic.Stack`1" /> is greater than the available space from <paramref name="arrayIndex" /> to the end of the destination <paramref name="array" />.</exception>
// Token: 0x06002497 RID: 9367 RVA: 0x000AAAA0 File Offset: 0x000A8CA0
[__DynamicallyInvokable]
public void CopyTo(T[] array, int arrayIndex)
{
if (array == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
if (arrayIndex < 0 || arrayIndex > array.Length)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
if (array.Length - arrayIndex < this._size)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
}
Array.Copy(this._array, 0, array, arrayIndex, this._size);
Array.Reverse(array, arrayIndex, this._size);
}
/// <summary>Copies the elements of the <see cref="T:System.Collections.ICollection" /> to an <see cref="T:System.Array" />, starting at a particular <see cref="T:System.Array" /> index.</summary>
/// <param name="array">The one-dimensional <see cref="T:System.Array" /> that is the destination of the elements copied from <see cref="T:System.Collections.ICollection" />. The <see cref="T:System.Array" /> must have zero-based indexing.</param>
/// <param name="arrayIndex">The zero-based index in <paramref name="array" /> at which copying begins.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="array" /> is <see langword="null" />.</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="arrayIndex" /> is less than zero.</exception>
/// <exception cref="T:System.ArgumentException">
/// <paramref name="array" /> is multidimensional.
/// -or-
/// <paramref name="array" /> does not have zero-based indexing.
/// -or-
/// The number of elements in the source <see cref="T:System.Collections.ICollection" /> is greater than the available space from <paramref name="arrayIndex" /> to the end of the destination <paramref name="array" />.
/// -or-
/// The type of the source <see cref="T:System.Collections.ICollection" /> cannot be cast automatically to the type of the destination <paramref name="array" />.</exception>
// Token: 0x06002498 RID: 9368 RVA: 0x000AAB00 File Offset: 0x000A8D00
[__DynamicallyInvokable]
void ICollection.CopyTo(Array array, int arrayIndex)
{
if (array == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
if (array.Rank != 1)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
if (array.GetLowerBound(0) != 0)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
if (arrayIndex < 0 || arrayIndex > array.Length)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
if (array.Length - arrayIndex < this._size)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
}
try
{
Array.Copy(this._array, 0, array, arrayIndex, this._size);
Array.Reverse(array, arrayIndex, this._size);
}
catch (ArrayTypeMismatchException)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
}
}
/// <summary>Returns an enumerator for the <see cref="T:System.Collections.Generic.Stack`1" />.</summary>
/// <returns>An <see cref="T:System.Collections.Generic.Stack`1.Enumerator" /> for the <see cref="T:System.Collections.Generic.Stack`1" />.</returns>
// Token: 0x06002499 RID: 9369 RVA: 0x000AABA0 File Offset: 0x000A8DA0
[__DynamicallyInvokable]
public Stack<T>.Enumerator GetEnumerator()
{
return new Stack<T>.Enumerator(this);
}
// Token: 0x0600249A RID: 9370 RVA: 0x000AABA8 File Offset: 0x000A8DA8
[__DynamicallyInvokable]
IEnumerator<T> IEnumerable<!0>.GetEnumerator()
{
return new Stack<T>.Enumerator(this);
}
/// <summary>Returns an enumerator that iterates through a collection.</summary>
/// <returns>An <see cref="T:System.Collections.IEnumerator" /> that can be used to iterate through the collection.</returns>
// Token: 0x0600249B RID: 9371 RVA: 0x000AABB5 File Offset: 0x000A8DB5
[__DynamicallyInvokable]
IEnumerator IEnumerable.GetEnumerator()
{
return new Stack<T>.Enumerator(this);
}
/// <summary>Sets the capacity to the actual number of elements in the <see cref="T:System.Collections.Generic.Stack`1" />, if that number is less than 90 percent of current capacity.</summary>
// Token: 0x0600249C RID: 9372 RVA: 0x000AABC4 File Offset: 0x000A8DC4
[__DynamicallyInvokable]
public void TrimExcess()
{
int num = (int)((double)this._array.Length * 0.9);
if (this._size < num)
{
T[] array = new T[this._size];
Array.Copy(this._array, 0, array, 0, this._size);
this._array = array;
this._version++;
}
}
/// <summary>Returns the object at the top of the <see cref="T:System.Collections.Generic.Stack`1" /> without removing it.</summary>
/// <returns>The object at the top of the <see cref="T:System.Collections.Generic.Stack`1" />.</returns>
/// <exception cref="T:System.InvalidOperationException">The <see cref="T:System.Collections.Generic.Stack`1" /> is empty.</exception>
// Token: 0x0600249D RID: 9373 RVA: 0x000AAC24 File Offset: 0x000A8E24
[__DynamicallyInvokable]
public T Peek()
{
if (this._size == 0)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyStack);
}
return this._array[this._size - 1];
}
/// <summary>Removes and returns the object at the top of the <see cref="T:System.Collections.Generic.Stack`1" />.</summary>
/// <returns>The object removed from the top of the <see cref="T:System.Collections.Generic.Stack`1" />.</returns>
/// <exception cref="T:System.InvalidOperationException">The <see cref="T:System.Collections.Generic.Stack`1" /> is empty.</exception>
// Token: 0x0600249E RID: 9374 RVA: 0x000AAC48 File Offset: 0x000A8E48
[__DynamicallyInvokable]
public T Pop()
{
if (this._size == 0)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyStack);
}
this._version++;
T[] array = this._array;
int num = this._size - 1;
this._size = num;
T result = array[num];
this._array[this._size] = default(T);
return result;
}
/// <summary>Inserts an object at the top of the <see cref="T:System.Collections.Generic.Stack`1" />.</summary>
/// <param name="item">The object to push onto the <see cref="T:System.Collections.Generic.Stack`1" />. The value can be <see langword="null" /> for reference types.</param>
// Token: 0x0600249F RID: 9375 RVA: 0x000AACAC File Offset: 0x000A8EAC
[__DynamicallyInvokable]
public void Push(T item)
{
if (this._size == this._array.Length)
{
T[] array = new T[(this._array.Length == 0) ? 4 : (2 * this._array.Length)];
Array.Copy(this._array, 0, array, 0, this._size);
this._array = array;
}
T[] array2 = this._array;
int size = this._size;
this._size = size + 1;
array2[size] = item;
this._version++;
}
/// <summary>Copies the <see cref="T:System.Collections.Generic.Stack`1" /> to a new array.</summary>
/// <returns>A new array containing copies of the elements of the <see cref="T:System.Collections.Generic.Stack`1" />.</returns>
// Token: 0x060024A0 RID: 9376 RVA: 0x000AAD2C File Offset: 0x000A8F2C
[__DynamicallyInvokable]
public T[] ToArray()
{
T[] array = new T[this._size];
for (int i = 0; i < this._size; i++)
{
array[i] = this._array[this._size - i - 1];
}
return array;
}
// Token: 0x04002008 RID: 8200
private T[] _array;
// Token: 0x04002009 RID: 8201
private int _size;
// Token: 0x0400200A RID: 8202
private int _version;
// Token: 0x0400200B RID: 8203
[NonSerialized]
private object _syncRoot;
// Token: 0x0400200C RID: 8204
private const int _defaultCapacity = 4;
// Token: 0x0400200D RID: 8205
private static T[] _emptyArray = new T[0];
/// <summary>Enumerates the elements of a <see cref="T:System.Collections.Generic.Stack`1" />.</summary>
/// <typeparam name="T" />
// Token: 0x020007F8 RID: 2040
[__DynamicallyInvokable]
[Serializable]
public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
{
// Token: 0x06004453 RID: 17491 RVA: 0x0011E274 File Offset: 0x0011C474
internal Enumerator(Stack<T> stack)
{
this._stack = stack;
this._version = this._stack._version;
this._index = -2;
this.currentElement = default(T);
}
/// <summary>Releases all resources used by the <see cref="T:System.Collections.Generic.Stack`1.Enumerator" />.</summary>
// Token: 0x06004454 RID: 17492 RVA: 0x0011E2A2 File Offset: 0x0011C4A2
[__DynamicallyInvokable]
public void Dispose()
{
this._index = -1;
}
/// <summary>Advances the enumerator to the next element of the <see cref="T:System.Collections.Generic.Stack`1" />.</summary>
/// <returns>
/// <see langword="true" /> if the enumerator was successfully advanced to the next element; <see langword="false" /> if the enumerator has passed the end of the collection.</returns>
/// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created.</exception>
// Token: 0x06004455 RID: 17493 RVA: 0x0011E2AC File Offset: 0x0011C4AC
[__DynamicallyInvokable]
public bool MoveNext()
{
if (this._version != this._stack._version)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
}
bool flag;
if (this._index == -2)
{
this._index = this._stack._size - 1;
flag = (this._index >= 0);
if (flag)
{
this.currentElement = this._stack._array[this._index];
}
return flag;
}
if (this._index == -1)
{
return false;
}
int num = this._index - 1;
this._index = num;
flag = (num >= 0);
if (flag)
{
this.currentElement = this._stack._array[this._index];
}
else
{
this.currentElement = default(T);
}
return flag;
}
/// <summary>Gets the element at the current position of the enumerator.</summary>
/// <returns>The element in the <see cref="T:System.Collections.Generic.Stack`1" /> at the current position of the enumerator.</returns>
/// <exception cref="T:System.InvalidOperationException">The enumerator is positioned before the first element of the collection or after the last element.</exception>
// Token: 0x17000F81 RID: 3969
// (get) Token: 0x06004456 RID: 17494 RVA: 0x0011E36F File Offset: 0x0011C56F
[__DynamicallyInvokable]
public T Current
{
[__DynamicallyInvokable]
get
{
if (this._index == -2)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted);
}
if (this._index == -1)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded);
}
return this.currentElement;
}
}
/// <summary>Gets the element at the current position of the enumerator.</summary>
/// <returns>The element in the collection at the current position of the enumerator.</returns>
/// <exception cref="T:System.InvalidOperationException">The enumerator is positioned before the first element of the collection or after the last element.</exception>
// Token: 0x17000F82 RID: 3970
// (get) Token: 0x06004457 RID: 17495 RVA: 0x0011E398 File Offset: 0x0011C598
[__DynamicallyInvokable]
object IEnumerator.Current
{
[__DynamicallyInvokable]
get
{
if (this._index == -2)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted);
}
if (this._index == -1)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded);
}
return this.currentElement;
}
}
/// <summary>Sets the enumerator to its initial position, which is before the first element in the collection. This class cannot be inherited.</summary>
/// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created.</exception>
// Token: 0x06004458 RID: 17496 RVA: 0x0011E3C6 File Offset: 0x0011C5C6
[__DynamicallyInvokable]
void IEnumerator.Reset()
{
if (this._version != this._stack._version)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
}
this._index = -2;
this.currentElement = default(T);
}
// Token: 0x04003513 RID: 13587
private Stack<T> _stack;
// Token: 0x04003514 RID: 13588
private int _index;
// Token: 0x04003515 RID: 13589
private int _version;
// Token: 0x04003516 RID: 13590
private T currentElement;
}
}
}