混合类型通用C#堆栈(链接列表实现)

时间:2018-09-27 04:34:28

标签: c# generics stack

我意识到在大多数情况下,拥有一个同类型的,类型安全的堆栈会很有益,但是我很好奇这是否可行,因为有人要求我为接受所有类型的练习创建一个堆栈。

所以我目前有一个通用的链表Stack类,我想知道是否有任何方法可以使Node类成为通用类,以便Next节点可以具有不同的类型。我知道我可以通过仅使所有类型参数object而不是使用泛型来使堆栈接受所有类型,但是我被警告对值类型装箱/拆箱/上载其所有元素的性能影响到基础对象类。

所以我继续将其实现为通用,但是无法找到允许每个节点使用不同类型的解决方案。如果我想避免使用object方法,是否可以解决?即使完全采用其他方法,也不一定必须采用这种方法。

我希望这有道理!无论如何,这是我目前拥有的实现。请让我知道您的想法。

Node.cs

namespace DataStructures
{
    class Node<T>
    {
        public T Value { get; private set; }
        public Node<T> Next { get; set; }

        public Node(T value)
        {
            Value = value;
        }
    }
}

Stack.cs

namespace DataStructures
{
    class Stack<T>
    {
        private Node<T> root;
        public int Size { get; private set; } = 0;

        public Stack()
        {

        }

        public Stack(params T[] values)
        {
            foreach (var value in values)
                Push(value);
        }

        public void Push(T value)
        {
            if (value == null)
                throw new ArgumentNullException("value", "You cannot push a null value onto the stack");

            var newNode = new Node<T>(value);

            if (root != null)
                newNode.Next = root;

            root = newNode;

            Size++;
        }

        public dynamic Peek()
        {
            if (root == null)
                return null;

            return root.Value;
        }

        public T Pop()
        {
            if (root == null)
                throw new InvalidOperationException("The stack is empty, nothing to pop");

            Size--;

            var popped = root.Value;
            root = root.Next;
            return popped;
        }

        public bool TryPop(out dynamic popped)
        {
            if (root == null)
            {
                popped = null;
                return false;
            }

            else
            {
                popped = Pop();
                return true;
            }
        }

        public bool IsEmpty() => root == null ? true : false;

        public void Clear()
        {
            root = null;
        }
    }
}

0 个答案:

没有答案