2012-12-20 15 views
6

Co mam to proste stwierdzenie przełącznikZmienna problem inicjalizacji w instrukcji switch

Control myControl; 
switch(x) 
{ 
    case TabType.Edit: 
    { 
     myControl= ...; 
    } 

    case TabType.View: 
    { 

     myControl= ...; 
    } 
} 

myPageView.Controls.Add(myControl); 

W tej sytuacji kompilator mówi mi, że

zmienna lokalna myControl nie może być zainicjowana przed uzyskaniem dostępu

Jaki jest najlepszy sposób na uniknięcie tej sytuacji?

Jedną opcją jest zainicjowanie myControl przed instrukcją przełącznika. Ale w tym przypadku wykonuję jeszcze jedną niepotrzebną inicjalizację.

Przypadek 1:

Control myControl = null; 
switch(x) 
{ 
    case TabType.Edit: 
    { 
     myControl= ...; 
    } 

    case TabType.View: 
    { 

     myControl= ...; 
    } 
} 

myPageView.Controls.Add(myControl); 

Następna opcja to zmienić drugą sprawę z default. Po tym kompilator "zrozumie", że myControl i tak zostanie zainicjowany i nie wyrzuci wyjątku.

Przypadek 2:

Control myControl; 
switch(x) 
{ 
    case TabType.Edit: 
    { 
     myControl= ...; 
    } 

    default: 
    { 

     myControl= ...; 
    } 
} 

myPageView.Controls.Add(myControl); 

Ale ta sprawa nie wygląda tak dobrze, bo po dodaniu nowych właściwości do mojego wyliczenia to zrobi domyślne dla wszystkich innych typów (programista może łatwo zapomnieć, aby zmienić tutaj lub nie może być konieczne inicjowanie myControl dla innych typów wyliczeniowych).

Jakie jest najlepsze podejście w takich sytuacjach?

+0

Kompilator daje odpowiedź .. Wystarczy ustawić go na null lokalny swój błąd „zmienna myControl nie może zostać zainicjowana przed uzyskaniem dostępu” – MethodMan

Odpowiedz

5

Twój przykładowy kod oznacza, że ​​będą zawsze wykorzystywać zmiennej myControl po bloku switch. Jeśli tak jest, powinieneś albo wstępnie zainicjalizować zmienną, albo dodać klauzulę default (jak wspomniałeś).

Jeśli obawiasz się, że można wprowadzić nową wyliczoną wartość, możesz rzucić znaczący wyjątek w klauzuli default. To zabezpieczy cię przed uzyskaniem bardziej niejednoznacznego NullReferenceException, gdy spróbujesz później wyłuskać zmienną.

+2

+1 za zgłoszenie wyjątku, gdy przypadek 'default' jest trafienie. Również dobra alternatywa. –

+1

Dziękuję wszystkim :) Klauzula domyślna z rzucaniem znaczącego wyjątku to miłe podejście. –

+0

Chuck Norris może bezpiecznie ocenić odniesienie zerowe bez uzyskania wyjątku NullReferenceException – user93353

3

Trzecia opcja: validate instancja została stworzona przed przystąpieniem (zamiast opierania się na to są przypisane):

Control mycontrol = null; 
switch (x){ 
    // ... 
} 
if (myControl != null){ 
    // add to controls list, manipulate, etc. 
} 

Można też dodać default: spadkiem przez przypadek do wartości default(TabType):

switch (x){ 
    case TabType.Two: 
    // ... 
    case TabType.Three: 
    // ... 
    case TabType.One: 
    default: 
    // .. 
} 
+1

Twój Drugi przypadek był jego drugi przypadek. – Servy

+1

@ServyL tak, ale zrobiłem to wyraźną deklarację zamiast zwolnić wartość 'default (Tabtype)' i po prostu użyć 'default:'. –

+0

@DJKRAZE Typo, poprawiono. – Servy

2

Myślę, że default istnieje specjalnie dla tych sytuacji.

dodając kilka nowych właściwości do mojego wyliczenia to zrobi domyślne dla wszystkich innych typów

Pozwoli to kod do pracy na domyślnym założeniu (wyjątek lub ustawiony na wartość dobrze zna), a tym samym swoje Kod działa również w sytuacjach nie planowanych wcześniej.

Oczywiście, po zaimplementowaniu nowych właściwości i oczekiwaniu na inne zachowanie kodu, pominięcie aktualizacji tego przełącznika będzie łatwym do zauważenia błędem.

0

Musisz wykonać jedną z dwóch opcji; albo określ wartość początkową przed switch, albo dodaj obudowę default, aby kompilator wiedział na pewno, że switch zainicjuje zmienną.

Sugerowałbym, że jeśli przełącznik nie zainicjalizuje zmiennej, możliwe jest, że chcesz rzucić wyjątek. W takim przypadku wystarczy dodać ten kod do obudowy default.W ten sposób jest jasne, kiedy programista zapomina dodać wartość case, aby uzyskać nową wartość wyliczeniową, a nie po cichu nie działa.

1

zrobić jeszcze jeden niepotrzebny initalization

Ja też nie lubię.

Tak jak wiele osób już powiedziało, dodaj dodatkową sekcję default: do swojego oświadczenia switch. Tak:

Control myControl; 
switch(x) 
{ 
    case TabType.Edit: 
    myControl= ...; 
    break; 

    case TabType.View: 
    myControl= ...; 
    break; 

    default: 
    throw new Exception("Unexpected value of x: " + x);   
} 

myPageView.Controls.Add(myControl); 

To dlatego, że z pytaniem rozumiemy, że wiesz że x zawsze będzie mieć jeden z tych dwóch wartości. Kompilator tego nie wie. Powyższy kod to powie.

Powiązane problemy