Odpowiedzi udzielone do tej pory są bardzo mylące. Prawidłowa analiza problemu rozpoczyna się od odczytywania komunikatu o błędzie. Komunikat o błędzie mówi ci, co faktycznie jest źle:
„lokalna zmienna o nazwie«matryca»nie może zostać uznane w tym zakresie, ponieważ dałoby to inny sens«matrycy», który jest już używany w ' Zakres dla oznaczenia czegoś innego:
Przeczytaj uważnie .Mówi ci dokładnie, która reguła C# jest naruszona, a mianowicie , że nie możesz używać tej samej nazwy do odniesienia się do dwóch różnych rzeczy w tym samym zakresie. (W rzeczywistości komunikat o błędzie jest nieco błędny, powinien powiedzieć "lokalny obszar deklaracji zmiennych", gdzie jest napisane "zakres", ale jest to dość rozwlekłe).
Ta reguła jest udokumentowana w specyfikacji C# 4.0, sekcja 7.6. 2.1: Proste nazwy, niezmienne znaczenie w blokach.
(Jest również nielegalne posiadanie dwóch zmiennych lokalnych o tej samej nazwie w nakładających przestrzenie deklaracji. Kompilator może być zgłoszenie tego błędu, jak również, ale zgłasza bardziej ogólny błąd w tym przypadku).
Czy te zmienne nie są w różnych zakresach, więc nie byłbym w stanie uzyskać dostępu do pierwszej macierzy poza instrukcją if?
Tak. To stwierdzenie jest nieistotne: , ale nie ma znaczenia. Błąd tutaj jest taki, że ta sama prosta nazwa została użyta w odniesieniu do dwóch różnych rzeczy w tej samej lokalnej przestrzeni deklaracji zmiennej.
Rozważmy następujący scenariusz:
class C
{
int x;
void M()
{
x = 10; // means "this.x"
for(whatever)
{
int x = whatever;
}
}
}
samą ofertę. Błąd tutaj polega na tym, że prosta nazwa "x" została użyta w zewnętrznym polu deklaracji, aby odwołać się do this.x, i została użyta w wewnętrznej przestrzeni deklaracji do określenia "zmiennej lokalnej". Używanie tej samej prostej nazwy do odwoływania się do dwóch różnych rzeczy w tym samym polu deklaracji - pamiętaj, że wewnętrzna przestrzeń deklaracji jest częścią części zewnętrznej - jest zarówno niebezpieczna, , jak i jest niezgodna z prawem.
Jest to mylące z oczywistych powodów; ma się uzasadnione oczekiwanie, że nazwa będzie oznaczać to samo wszędzie w przestrzeni deklaracji, w której jest używana po raz pierwszy. Jest to niebezpieczne, ponieważ niewielkie zmiany kodu są podatne na zmianę znaczenia:
class C
{
int x;
void M()
{
int x;
x = 10; // no longer means "this.x"
for(whatever)
{
x = whatever;
}
}
}
Jeśli przestrzenie deklarację, w której proste nazwy są najpierw używane są nie nakładających to jest legalne do prostych nazw odnosi się do różnych rzeczy:
class C
{
int x;
void M()
{
{
x = 10; // means "this.x"
}
for(whatever)
{
int x = whatever; // Legal; now the
}
}
}
Aby uzyskać więcej informacji, i zabawna historia o smażone jedzenie, zobacz
http://blogs.msdn.com/b/ericlippert/archive/tags/simple+names/
Nawet jeśli pytanie się kwalifikuje, zapobiega to nieostrożnym błędom. –
tutaj [http://bytes.com/topic/c-sharp/answers/659303-already-used-child-scope-denote-something-else] możesz znaleźć wyjaśnienie od Jona Skeeta. I tutaj http://stackoverflow.com/questions/296755/child-scope-cs0136 także przez Jona Skeeta. –
@Tim: Tak, ale za każdym razem trzeba tworzyć niepotrzebne nowe nazwy zmiennych, coś podobnego musi być użyte, aby zadowolić kompilator. IMO, jeśli kod jest jasny, nie spowoduje to żadnego problemu. Widzę, co każda macierz oznaczała bez robienia: matrixTemporary, matrixReal, itp. –