2012-12-27 26 views
5

Implementuję ogólny stos przy użyciu macierzy. ale pojawia się błąd jak:Implementowanie ogólnego stosu przy użyciu tablicy w języku C#

Nie można stosować z indeksowania [] w celu wyrażenia typu 'T'

na linii:

data[SP] = data; 

, jak rozwiązać ten problem? Sprawdziłem też ten link:

Cannot apply indexing to an expression of type 'T'

powinny implementować ten sam dylemat tutaj w mojej sytuacji zbyt? czy jest jakaś inna najlepsza dostępna opcja?

Oto mój kod:

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(); 
    } 
} 

góry dzięki.

+5

Czy istnieje szczególny powód, dla którego wdrażasz stos? Jeśli nie, możesz po prostu użyć ['System.Collections.Generic.Stack '] (http://msdn.microsoft.com/en-us/library/3278tedw.aspx) – Waldfee

Odpowiedz

4

Powinieneś zmienić nazwę parametru "data" w metodzie (Push) na inną nazwę.

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

jeśli istnieje pole i parametr o tej samej nazwie, parametr jest silniejsza, lub użyć „to” słowo kluczowe i zmienić linię:

 this.data[SP] = data; 

Nawiasem mówiąc, możesz użyć Stack<T> .net ready made class, chyba że implementujesz z powodów edukacyjnych!

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

+0

o człowieku! to tutaj nazwa błędu kolizyjnego. :(bardzo dziękuję za wskazanie tego. –

+1

Każda odpowiedź została odrzucona z wyjątkiem tego, mimo że wszystkie odpowiedzi są poprawne.Czy to nie dziwne ... –

+0

Nie wiem !, może !, ale ja również mam downvotes, jak myślę –

5

To jest kwestia zakresu, w linii

data[SP] = data; 

data odnosi się w obu przypadkach do lokalnego parametru data która jest typu T, nie T[], stąd błąd. Można zmienić nazwę zmiennej lokalnej lub bezpośrednio odwoływać się do zmiennej członka używając this:

this.data[SP] = data; 
1

masz parametr w Push() nazwie data. Kompilator woli użyć bardziej wąskiej zmiennej zakresu zamiast właściwości o nazwie data. Ponieważ parametr to T, a nie T[], nie można uzyskać do niego dostępu za pomocą narzędzia indeksującego.

Rozwiązaniem jest zmiana nazwy tego parametru lub użycie this.data. Zdecydowanie zalecamy zmianę nazwy parametru.

4

Podejrzewam, że można oczekiwać data oznacza parametr formalny, gdy jesteś myślenia o formalnym parametru, a dla data oznaczać this.data gdy jesteś myślenia o polu. Kompilator C# nie może odczytać twojego umysłu; data w tym przypadku zawsze będzie oznaczać parametr formalny, który nie jest tablicą.

Zamiast "danych", nazwij tablicę "wartościami" i wartością, która ma zostać naciśnięta "wartość".

Poza tym używanie prywatnych automatycznych właściwości zamiast prywatnych pól jest legalne, ale niezwyczajne. Czy jest jakiś powód, dla którego to robisz? Większość ludzi korzysta tylko z właściwości automatycznych dla właściwości publicznych, chronionych lub wewnętrznych.

+0

Nice. :) dzięki za odpowiedź. Używam tych właściwości jako prywatnych, ponieważ klient mojego stosu nie powinien uzyskiwać bezpośredniego dostępu do tych właściwości innych niż za pomocą metod push i pop. jaki najlepszy sposób sugerujesz tutaj Eric? –

+1

@AlagesanPalani: Zdecydowanie powinny być prywatne, ale zazwyczaj jeśli chcesz przechowywać prywatne dane, powinieneś powiedzieć "prywatne wartości T []", a nie "prywatne wartości T [] {get; zestaw; }; '. Ta pierwsza tworzy pole, druga tworzy niewidzialne pole prywatne, a następnie owija wokół niego obiekt pobierający i ustawiający. To nie jest złe, ale jest trochę dziwne, dlatego zastanawiałem się, czy masz jakiś konkretny powód, aby to zrobić. –

+0

OK, masz na myśli, jeśli ujawniasz coś światu zewnętrznemu, właściwości automatyczne są dobrym kandydatem. jeśli próbujesz ukryć coś ze świata zewnętrznego, uczyń je prywatnym polem. Dobra praktyka. ok pewnie. to dobra nauka. dzięki jeszcze raz. –

Powiązane problemy