HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

Which is the most correct pattern for using Stack.Pop?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
themoststackcorrectforusingwhichpatternpop

Problem

There at least 2 patterns of using Stack.Pop

-

private Stack availableResources;
...
if (availableResources.Count > 0) 
{
  resource = availableResources.Pop();
  ...
}


-

private Stack availableResources;
...
try 
{
  resource = availableResources.Pop();
  ...
}
catch (InvalidOperationException e)
{
  ...
}


I'd like to ask people, which of 2 is preferable? If possible, argument your answer.

Solution

Program defensively and use option 1.

Since the Stack class provides the ability to check whether it contains anything before trying to Pop a value from it, you should do the check and avoid using the exception for flow control.

If you want to avoid doing the if check throughout your application, you could create a TryPop extension.

public static class StackExtensions
{
    public static bool TryPop(this Stack stack, out T value)
    {
        if (stack.Count > 0)
        {
            value = stack.Pop();
            return true;
        }

        value = default(T);
        return false;
    }
}


It could be used in the following way:

T resource;
if (availableResources.TryPop(out resource)) 
{
    // use `resource` for something
}


It's worth noting that this approach is only suitable if the Stack is not accessed concurrently! - If it is, and you are using .NET 4.0 onwards then you should use ConcurrentStack, otherwise create your own concurrent stack which encapsulates a Stack and manages access to it with locks.

Code Snippets

public static class StackExtensions
{
    public static bool TryPop<T>(this Stack<T> stack, out T value)
    {
        if (stack.Count > 0)
        {
            value = stack.Pop();
            return true;
        }

        value = default(T);
        return false;
    }
}
T resource;
if (availableResources.TryPop(out resource)) 
{
    // use `resource` for something
}

Context

StackExchange Code Review Q#18531, answer score: 17

Revisions (0)

No revisions yet.