title: Mixed-Type Generic C# Stack (Linked List Implementation)
body: <p>I realize that in most cases, it would be beneficial to have a homogeneous, type-safe stack, but I'm curious if this is possible, as I was asked to create a Stack for an exercise which accepts all types.</p>
  
  <p>So I currently have a generic linked-list Stack class, and I'm wondering if there's any way to make the Node class generic so that the Next node can be of a different type. I know I can make the stack accept all types by just making the all the type parameters <code>object</code> instead of using a generic, but I was warned of the performance implications of boxing &amp; unboxing of value types / upcasting all of it's elements to the base object class. </p>
  
  <p>So I went ahead an implemented it as Generic, but was unable to find a solution that allowed different types for each Node. If I wanted to avoid the <code>object</code> approach, is there a possible solution? Even if it takes a different approach altogether, it doesn't necessarily have to fit this approach.</p>
  
  <p>I hope this makes sense! At any rate, here's the implementation I currently have. Please let me know what you think.</p>
  
  <h3>Node.cs</h3>
  
  <pre class="lang-cs prettyprint-override"><code>namespace DataStructures
  {
      class Node&lt;T&gt;
      {
          public T Value { get; private set; }
          public Node&lt;T&gt; Next { get; set; }
  
          public Node(T value)
          {
              Value = value;
          }
      }
  }
  </code></pre>
  
  <h3>Stack.cs</h3>
  
  <pre class="lang-cs prettyprint-override"><code>namespace DataStructures
  {
      class Stack&lt;T&gt;
      {
          private Node&lt;T&gt; 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&lt;T&gt;(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() =&gt; root == null ? true : false;
  
          public void Clear()
          {
              root = null;
          }
      }
  }
  </code></pre>