2012-12-20 13 views
6

gì tôi có là đơn giản câu lệnh switchBiến vấn đề khởi tạo trong câu lệnh switch

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

    case TabType.View: 
    { 

     myControl= ...; 
    } 
} 

myPageView.Controls.Add(myControl); 

Trong biên dịch tình huống này nói với tôi rằng

địa phương biến myControl có thể không được khởi tạo trước khi truy cập

Vì vậy, cách tốt nhất để tránh tình trạng này là gì?

Một tùy chọn là khởi tạo myControl trước câu lệnh chuyển đổi. Nhưng trong trường hợp này tôi làm thêm một lần nữa.

TRƯỜNG HỢP 1:

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

    case TabType.View: 
    { 

     myControl= ...; 
    } 
} 

myPageView.Controls.Add(myControl); 

tùy chọn kế tiếp là thay đổi trường hợp thứ hai với default. Sau đó trình biên dịch sẽ "hiểu" rằng myControl sẽ được anyway khởi tạo và sẽ không ném ngoại lệ.

TRƯỜNG HỢP 2:

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

    default: 
    { 

     myControl= ...; 
    } 
} 

myPageView.Controls.Add(myControl); 

Nhưng trường hợp này không giống như vậy tốt, bởi vì sau khi thêm một số đặc tính mới để enum của tôi nó sẽ làm mặc định cho tất cả các loại khác (nhà phát triển có thể dễ dàng quên thay đổi mã ở đây hoặc nó có thể không cần thiết để khởi tạo myControl cho các loại enum khác).

Cách tiếp cận tốt nhất trong những trường hợp như thế nào?

+0

Trình biên dịch cung cấp cho bạn câu trả lời .. chỉ cần đặt thành null cục bộ lỗi của bạn "myControl biến có thể không được khởi tạo trước khi truy cập" – MethodMan

Trả lời

5

Mẫu mã của bạn cho biết rằng bạn sẽ luôn sử dụng biến số myControl sau khối chuyển đổi. Nếu đó là trường hợp, thì bạn nên khởi tạo lại biến, hoặc thêm một mệnh đề default (như bạn đã đề cập).

Nếu bạn lo ngại rằng một giá trị được liệt kê mới có thể được giới thiệu, thì bạn có thể ném một ngoại lệ có ý nghĩa trong mệnh đề default. Điều đó sẽ bảo vệ bạn khỏi việc không rõ ràng hơn NullReferenceException khi bạn cố gắng dereference biến sau này.

+2

+1 để ném ngoại lệ khi trường hợp 'mặc định' là đánh. Cũng là một lựa chọn tốt. –

+1

Nhờ tất cả mọi người :) Điều khoản mặc định với ném ngoại lệ có ý nghĩa là cách tiếp cận tốt đẹp. –

+0

Chuck Norris có thể an toàn lựa chọn một tham chiếu Null mà không nhận được một NullReferenceException – user93353

3

tùy chọn thứ ba: Validate một thể hiện được tạo ra trước khi tiến hành (thay vì dựa vào nó được gán):

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

Bạn cũng có thể thêm default: trường hợp sụp đổ qua với giá trị default(TabType):

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

Trường hợp thứ hai của bạn là trường hợp thứ hai của mình. – Servy

+1

@ServyL có, nhưng tôi đã làm cho nó một tuyên bố rõ ràng thay vì miễn 'mặc định (Tabtype)' giá trị và chỉ sử dụng 'mặc định:'. –

+0

@DJKRAZE Typo, đã được sửa. – Servy

2

Tôi nghĩ rằng default tồn tại đặc biệt cho những tình huống này.

thêm một số đặc tính mới để enum của tôi nó sẽ làm mặc định cho tất cả các loại khác

Nó sẽ cho phép mã của bạn để làm việc trên tiền đề mặc định (Ném một ngoại lệ hoặc thiết lập một giá trị cũng biết) và do đó bạn mã làm việc cũng cho các tình huống không được lên kế hoạch trước đó.

Tất nhiên, khi bạn triển khai thuộc tính mới và mong đợi một hành vi khác của mã, hãy bỏ qua để cập nhật công tắc này sẽ là một lỗi dễ phát hiện.

0

Bạn phải thực hiện một trong hai tùy chọn; hoặc chỉ định giá trị ban đầu trước switch hoặc thêm default trường hợp để trình biên dịch biết chắc chắn rằng switch sẽ khởi tạo biến.

Tôi sẽ đề nghị rằng nếu công tắc không khởi tạo biến, có thể bạn chỉ muốn ném một ngoại lệ. Trong trường hợp đó, chỉ cần thêm mã đó vào trường hợp default.Bằng cách đó, rõ ràng khi thử nghiệm khi nhà phát triển quên thêm case cho giá trị enum mới, thay vì chỉ im lặng không hoạt động.

1

tôi làm thêm một initalization không cần thiết

Tôi cũng không thích điều đó.

Giống như nhiều người đã nói, hãy thêm một phần thêm default: vào câu hỏi switch của bạn. Như thế này:

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

Điều này là do từ câu hỏi của bạn chúng tôi hiểu rằng bạn biết rằng x sẽ luôn luôn có một trong hai giá trị. Trình biên dịch không biết điều đó. Đoạn mã trên sẽ cho bạn biết.