using System;
using System.Collections.Generic;
using System.Collections;
namespace StructScript
{
public class StackScript<T> : IEnumerable<T>
{
private T[] mArray;
private int mSize;
private const int mDefaultCapacity = 4;
private static T[] mEmptyArray = new T[0];
public StackScript()
{
mArray = mEmptyArray;
mSize = 0;
}
public StackScript(int capacity)
{
if (capacity < 0)
{
throw new IndexOutOfRangeException();
}
mArray = new T[capacity];
mSize = 0;
}
public int Count
{
get { return mSize; }
}
public void Clear()
{
Array.Clear(mArray, 0, mSize);
mSize = 0;
}
public bool Contains(T item)
{
int count = mSize;
EqualityComparer<T> c = EqualityComparer<T>.Default;
while (count-- > 0)
{
if (((Object)item) == null)
{
if (((Object)mArray[count]) == null)
return true;
}
else if (mArray[count] != null && c.Equals(mArray[count], item))
{
return true;
}
}
return false;
}
public T Pop()
{
if (mSize == 0)
{
throw new InvalidOperationException();
}
mSize--;
T item = mArray[mSize];
mArray[mSize] = default(T);
return item;
}
public void Push(T item)
{
if (mSize == mArray.Length)
{
T[] newArray = new T[(mArray.Length == 0) ? mDefaultCapacity : 2 * mArray.Length];
Array.Copy(mArray, 0, newArray, 0, mSize);
mArray = newArray;
}
mArray[mSize++] = item;
}
public IEnumerator<T> GetEnumerator()
{
return new Enumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator(this);
}
public struct Enumerator : IEnumerator<T>
{
private StackScript<T> _stack;
private int _index;
private T currentElement;
internal Enumerator(StackScript<T> stack)
{
_stack = stack;
_index = -2;
currentElement = default(T);
}
public void Dispose()
{
_index = -1;
}
public bool MoveNext()
{
bool retval;
if (_index == -2)
{ // First call to enumerator.
_index = _stack.mSize - 1;
retval = (_index >= 0);
if (retval)
currentElement = _stack.mArray[_index];
return retval;
}
if (_index == -1)
{ // End of enumeration.
return false;
}
retval = (--_index >= 0);
if (retval)
currentElement = _stack.mArray[_index];
else
currentElement = default(T);
return retval;
}
public T Current
{
get
{
if (_index < 0)
{
throw new InvalidOperationException();
}
return currentElement;
}
}
Object IEnumerator.Current
{
get
{
if (_index < 0)
{
throw new InvalidOperationException();
}
return currentElement;
}
}
void IEnumerator.Reset()
{
_index = -2;
currentElement = default(T);
}
}
}
}
附上,测试用例:
using System;
namespace StructScript
{
public class TestStack
{
public static void Main()
{
StackScript<string> numbers = new StackScript<string>();
numbers.Push("one");
numbers.Push("two");
numbers.Push("three");
numbers.Push("four");
numbers.Push("five");
// A stack can be enumerated without disturbing its contents.
foreach (string number in numbers)
{
Console.WriteLine(number);
}
Console.WriteLine("\nPopping '{0}'", numbers.Pop());
Console.WriteLine("\nstack2.Contains(\"four\") = {0}",
numbers.Contains("four"));
Console.WriteLine("\nstack2.Clear()");
numbers.Clear();
Console.WriteLine("\nstack2.Count = {0}", numbers.Count);
Console.ReadLine();
}
}
}