5

I am implementing a generic stack using array. But i get error as :

Cannot apply indexing with [] to an expression of type 'T'

on the line:

 data[SP] = data;

how to fix the issue? also i checked this link:

Cannot apply indexing to an expression of type 'T'

should i implement the same fix here in my situation too? or is there any other best option available?

Here is my code:

public class MyStack<T> 
{
    private T[] data { get; set; }
    private int SP { get; set; }
    private int Capacity { get; set; }
    public MyStack(int capacity)
    {
        this.Capacity = capacity;
        data = new T[Capacity];
        SP = -1;
        // it works here, dont know why??? ;)
        data[0] = default(T);
    }
    public void Push(T data)
    {
        ++SP;
        if(SP>=Capacity) growArray();
        // This is where i get error.
        data[SP] = data;
    }
    public T Pop()
    {
        if (SP < 0) throw new InvalidOperationException();
        T value = data[SP];
        data[SP] = default(T);
        SP--;
        return value;
    }
    public T Peak()
    {
        if (SP < 0) throw new InvalidOperationException();
        return data[SP];
    }
    private void growArray()
    {
        throw new NotImplementedException();
    }
}

Thanks in advance.

1

4 Answers 4

5

This is a scope issue, in the line

data[SP] = data;

data refers in both cases to the local parameter data which is of type T, not T[], hence the error. You can rename the local variable or explicitly reference the member variable using this:

this.data[SP] = data;
Sign up to request clarification or add additional context in comments.

Comments

5

I suspect that you expect data to mean the formal parameter when you are thinking about the formal parameter, and for data to mean this.data when you are thinking about the field. The C# compiler cannot read your mind; data in this case will always mean the formal parameter, which is not an array.

Instead of "data", name the array "values" and the value being pushed "value".

Also, it's legal but unusual to use private automatic properties instead of private fields. Is there some reason why you're doing that? Most people only use automatic properties for public, protected or internal properties.

5 Comments

Nice.:) thanks for the reply. I am using those properties as private, because my stack's client should not directly access those properties other than using the push and pop methods. what best way you suggest here Eric?
@AlagesanPalani: They definitely should be private, but typically if you wanted to store private data you'd say private T[] values;, not private T[] values { get; set; };. The former makes a field, the latter makes an invisible private field and then wraps a property getter and setter around it. It's not wrong, but it is a bit strange, which is why I wondered if you had some specific reason to do that.
Okay you mean to say, if you are exposing something to outside world, automatic properties are good candidate. if you are trying to hide something from outside world make them private field. As a good practice. okay sure. its a good learning. thanks again.
@EricLippert I use private automatic properties for the exact same reasons you would use public automatic properties, and don't understand why it would be considered strange. Oh, and it's so nice to see you posting more often! :)
@asawyer: I think of a property as being part of the "model". Color is a property of a car, so Color is a property of the Car class. Things that are "in the model" are the public surface of the type. I think of a field as being part of the "mechanism" -- how the model is implemented. You want to hide the mechanism and expose the model, so it seems strange to me to hide a property. Not wrong, just a bit strange.
4

You should rename the parameter 'data' in the method (Push) to another name.

        public void Push(T d)
        {
         .
         .
         data[SP] = d;
         .
         .

if there are a field and a parameter with the same name, the parameter is stronger, or you can use 'this' keyword and change this line to:

        this.data[SP] = data;

By the way, you can use Stack<T> .net ready made class, except if you are implementing for educational reasons!

This is the code of .net ready made Stack<T>

5 Comments

oh man! its a name collison bug i made here. :( thank you very much for pointing that out.
Every answer has been downvoted except for this one, even though all the answers are correct. Isn't that odd...
yeah, its really odd, actually i am waiting to accept your answer as you answered me first. but you know stackoverflow does not allow you to accept answer within 10 mins. :)
You do now. You didn't a few minutes ago. (I didn't downvote this, FYI)
hhhhhhh, never mind, the others have Kilos and Kilos, but it am the poorest one!
1

You have a parameter in Push() called data. The compiler prefers to use the more narrowly scoped variable, instead of the property called data. Because the parameter is a T and not T[], you cannot access it using an indexer.

The solution is to simply rename that parameter, or use this.data. I strongly recommend renaming the parameter.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.