4

Does anyone have any examples or ideas on how / what is the best way to implement a Stack class in C#? I understand that there is already a Stack class, but I need to understand how to actually implement a Stack class.

I also need advice on how to use Contracts in C# to specify preconditions, postconditions, and invariants for this class. I think I have used something similar before when creating models in the ASP.NET MVC architecture, but I'm not entirely sure if it is the same thing and works the same way. (I'm a bit lost on the preconditions/postconditions/invariants, if you couldn't already tell - so please bear with me.)

My main question - could someone give me advice on properly using Contracts for a class such as a Stack.

Yes, I have laid out effort:

public interface IStack
{
        void Push(Object e);
        Object Pop();
        Object Top();
        void EnsureCapacity();
    }
}

   public class Stack : IStack
{
    private Object[] elements;
    private int size = 0;

    public Stack()
    {
        elements = new Object[0];
    }

    public void Push(Object e)
    {
        // check if this array capacity has been reached and increase if needed
        EnsureCapacity();
        elements[size++] = e;
    }

    public Object Pop()
    {
        // check if the method call is invalid for the object's current state
        if (size == 0) throw new InvalidOperationException("Stack.Pop");

        Object result = elements[--size];
        elements[size] = null;

        return result;
    }

    public Object Top()
    {
        // check if the method call is invalid for the object's current state
        if (size == 0) throw new InvalidOperationException("Stack.top");
        return elements[(size - 1)];
    }

    private void EnsureCapacity()
    {
        if (elements.Length == size)
        {
            Object[] oldElements = elements;
            elements = new Object[(2 * size + 1)];
        }
    }
}
David Robinson
  • 77,383
  • 16
  • 167
  • 187
Cody
  • 8,686
  • 18
  • 71
  • 126
  • 4
    It appears you haven't laid out any effort on your part. Have you written any skeleton code? Do you have specific questions or problems? Or is your question "does anyone have any examples or ideas?" That is unacceptably vague. – abelenky Oct 05 '11 at 21:59
  • @abelenky Yes, I've written the interface as well as the constructor/push/pop/top. Just because I didn't post it, please do not assume that I haven't laid out any effort. The majority of my question is directed towards Contracts in C#, as I am a bit confused on how to use them appropriately. – Cody Oct 05 '11 at 22:01
  • Could someone please let me know why I am getting -2 on a question where I am trying to learn? – Cody Oct 05 '11 at 22:01
  • @DoctorOreo I believe it's because this question is being interpreted as a bit vague. I don't know that I agree with people downvoting you so hard, though. (Particularly without saying what you could do to improve) – Kevek Oct 05 '11 at 22:03
  • I have updated my question to be a bit more clear...does that help? – Cody Oct 05 '11 at 22:04
  • @DoctorOreo I hope so (I for one am not one of the downvoters). It may be useful to state why you think a Contract is necessary or what you want to do with it. Or why you think your current implementation is sub-par. Is there a specific portion of it you would like to optimize that you are concerned about? Is there a certain operation for which you want a Contract and would like advice in regard to how to do so? – Kevek Oct 05 '11 at 22:07
  • As far as why I would want a Contract..I don't necessarily, but on an upcoming Midterm the professor stated we would be wise to learn how to use Contracts and suggested that we begin using them with different types of classes (ie a Stack, linked list, etc). I'm trying to get ahead of the game and understand how it works so I can construct it on the fly. I also think it would be useful to include contracts in more of my applications, so this is a good learning thing all around. – Cody Oct 05 '11 at 22:10
  • Have you tried your code at all? There's several places where it just won't work – Rob Oct 05 '11 at 22:20
  • @DoctorOreo: much better now :) – sehe Oct 05 '11 at 23:00

2 Answers2

1

Many of collections implemented in c# are based on arrays. You could use array and add elements to the end, keep index of a top elemnet and increase it while new elements are pushed, of course array will "have to be extended" ( replaced by new one ) dynamically when new objects appear and there is no place for them in current array.

code contracts have pretty good documentation available at http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf

wiero
  • 2,176
  • 1
  • 19
  • 28
  • This is a great reference. Thank you, I'm taking a look at it now. I didn't know this existed. – Cody Oct 05 '11 at 22:11
1

If you want, for getting started using Microsoft Code Contracts, I made a blog post about it once. That post covers the very basic of preconditions, post-conditions, and invariants.

As a summary of the concepts, you can think of them as follows:

  • Precondition is what must be true prior to a method being executed -- what clients promise your method.
  • Invariant is what must remain publicly true at all times as far as clients of your class are concerned.
  • Postcondition is what must be true following a method execution -- what your method promises to clients.

So, off the top of my head, for a stack, an easy thing to think of might be an invariant. If you're modeling the stack with an array, you might declare an invariant on the class that the array is never set to null, for example you'd define the invariant method:

[ContractInvariantMethod]
private void ObjectInvariant()
{
   Contract.Invariant(elements != null);
}   

It looks like you've already got a precondition on your pop method - you want to say that it's incumbent on the user to make sure that the stack is not empty when he executes a pop. So, at the beginning of the pop method, you'd have:

Contract.Requires(size > 0);

And finally, you might specifiy a post-condition on pop, that size will always be less than it was before the pop operation (you could get more specific if you like):

Contract.Ensures(Contract.OldValue<int>(size) > size);

Good luck with it -- contracts are cool and useful. It's a very clean way to code.

Erik Dietrich
  • 6,080
  • 6
  • 26
  • 37