Conflicting user defined class name with inbuilt class name - C#

243 views Asked by At

I have the following code, where I am using the inbuilt C# Stack class in my own user defined Stack1 class. Everything works well with this user defined nomenclature. But, as soon as I change all references of my user defined Stack1 class, and call it as a Stack class - the compiler gets confused, and the C# inbuilt Stack classes that I am using inside my user defined Stack class no longer correspond to the inbuilt Systems.Collections.Stack class. But, fall back to the user defined StackHavingPopPushAndMinO1_2.Stack class. Do you know why this is happening, and is there any way I can keep my user defined Stack class name as Stack and still use the inbuilt Systems.Collections.Stack class inside it?

Please see: I already solved the issue by using the System.Collections.Generic.Stack<int> classes inside my user defined Stack class. But my intention here is that I don't want to change the name of my user defined Stack class - and still use the inbuilt Systems.Collection.Stack class inside it.

Please see: I also created an alias for System.Collections and appended it to the inbuild Stack classes I am using. But I was just wondering if there is some other way I can use my user defined Stack class which has the inbuilt Systems.Collections.Stackclasses in it.

Following is the code:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StackHavingPopPushAndMinO1_2
{
    class Stack1
    {
        Stack mainStack = new Stack();
        Stack supportingStack = new Stack();

        public void Push(int value)
        {
            mainStack.Push(value);
            if(supportingStack.Count==0 || value <= (int) supportingStack.Peek())
            {
                supportingStack.Push(value);
            }
        }

        public int Pop()
        {
            int value = -1;
            if(mainStack.Count>0)
            {
                value = (int) mainStack.Pop();
                if (value == (int) supportingStack.Peek())
                    supportingStack.Pop();
            }
            return value;
        }

        public int Min()
        {
            if (supportingStack.Count > 0)
                return (int) supportingStack.Peek();
            return -1;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Stack1 stack = new Stack1();
            stack.Push(60);
            stack.Push(10);
            stack.Push(50);
            Console.WriteLine(stack.Min());
            stack.Push(80);
            stack.Push(9);
            stack.Push(11);
            Console.WriteLine(stack.Min());
        }
    }
}

Everything works fine with the user defined class Stack1. But, as soon as I change the name of Stack1 to Stack, the compiler gets confused, and we get errors due to name conflict. Any light on this will be greatly helpful. Why does not the C# Compiler know the difference between the user defined Stack class, and the inbuilt Stack class?

1

There are 1 answers

0
Jon Skeet On BEST ANSWER

Why does not the C# Compiler know the difference between the user defined Stack class, and the inbuilt Stack class?

How would you expect it to do so? When it encounters a declaration of a variable like this:

Stack stack = null;

... which class should that refer to? I suspect that in some cases you'd want that to refer to StackHavingPopPushAndMinO1_2.Stack, and in other cases you'd want it to refer to System.Collections.Stack. The C# compiler follows very strict name lookup rules to determine the meaning of a name. You can find those rules in the C# specification, and I suspect that you'd be hard-pressed to design better rules.

In particular, looking at your class, you have:

class Stack // After renaming
{
    Stack mainStack = new Stack();
    ...

Presumably, you want the type of mainStack to be System.Collections.Stack, otherwise you'll end up with infinite recursion - but what rules would you expect to determine that?

Your options are:

  • Avoid the naming collision, which is generally the best approach
  • Use aliases to be explicit
  • Use fully-qualified names, e.g. System.Collections.Stack stack = null; instead of just the unqualified name