2010-04-22 38 views
9

Tôi có một truy vấn chèn trả về một int. Dựa trên đó int tôi có thể ném một ngoại lệ. Điều này có phù hợp để làm trong một tuyên bố chuyển đổi không?Có thể/Bạn có nên ném ngoại lệ trong câu lệnh chuyển đổi C# không?

switch (result) 
     { 

      case D_USER_NOT_FOUND: 
       throw new ClientException(string.Format("D User Name: {0} , was not found.", dTbx.Text)); 
      case C_USER_NOT_FOUND: 
       throw new ClientException(string.Format("C User Name: {0} , was not found.", cTbx.Text)); 
      case D_USER_ALREADY_MAPPED: 
       throw new ClientException(string.Format("D User Name: {0} , is already mapped.", dTbx.Text)); 
      case C_USER_ALREADY_MAPPED: 
       throw new ClientException(string.Format("C User Name: {0} , is already mapped.", cTbx.Text)); 
      default: 

       break; 
     } 

Tôi thường thêm câu lệnh ngắt vào công tắc nhưng chúng sẽ không bị nhấn. Đây có phải là thiết kế tồi không? Xin vui lòng chia sẻ bất kỳ ý kiến ​​/ đề nghị với tôi.

Cảm ơn, ~ ck ở San Diego

+2

Có vẻ như bạn đang cố gắng ánh xạ mã trả lại cho các ngoại lệ. Ý định của bạn là rõ ràng vì vậy tôi muốn nói rằng giải pháp này là tốt. –

Trả lời

3

Tôi không thực sự đồng ý với quy ước đặt tên biến của bạn;), nhưng tôi không hiểu tại sao những gì bạn đã làm sẽ là không phù hợp. Nó có vẻ như một cách khá thanh lịch để dịch một lỗi từ môi trường này sang môi trường khác.

Tôi giả định rằng "truy vấn chèn" của bạn là một dạng proc được lưu trữ.

+0

Vâng thưa bạn là chính xác. Cảm ơn. – Hcabnettek

0

Tôi nghĩ điều này là ổn. Có vẻ như bạn đang ánh xạ một mã trả về cho một ngoại lệ, sử dụng một câu lệnh switch. Miễn là không có quá nhiều trường hợp, đây không phải là vấn đề.

1

Nếu có thể nó sẽ tốt hơn nếu bạn ném bất cứ nơi nào kết quả không thành công được thiết lập, nếu không bạn sẽ phải thực hiện cả kiểm tra kết quả và ném. Nhưng dĩ nhiên là không thể.

Ngoài ra, tôi sẽ làm cho chuỗi lỗi của bạn thành tài nguyên hoặc hằng số với trình giữ chỗ để bạn không phải thay đổi nhiều địa điểm nếu bạn muốn thay đổi từ ngữ.

4

Không sao ... tại sao thiết kế này lại tệ?

Ngoài ra, vì loại ngoại lệ là giống nhau trong tất cả case s, bạn có thể xây dựng bảng tra cứu cho các thông báo lỗi. Điều đó sẽ giúp bạn tiết kiệm một số mã trùng lặp. Ví dụ:

static private Dictionary<int, string> errorMessages; 
static 
{ 
    // create and fill the Dictionary 
} 

// meanwhile, elsewhere in the code... 
if (result is not ok) { 
    throw new ClientException(string.Format(errorMessages[result], cTbx.Text, dTbx.Text)); 
} 

Trong thông điệp bản thân, bạn có thể chọn các thông số phù hợp với {0}, {1} vv

0

Không có gì sai với cách tiếp cận bạn đang dùng là. Các câu lệnh chuyển đổi dễ đọc hơn nhiều so với câu lệnh if/then (và có khả năng nhanh hơn). Một điều khác bạn có thể làm là tải các ngoại lệ có thể xảy ra trong một số điện thoại

Dictionary<Result_Type, Exception> 

và kéo ngoại lệ từ đó. Nếu bạn có nhiều câu lệnh chuyển đổi, điều này sẽ làm cho mã nhỏ gọn hơn (và bạn có thể thêm và loại bỏ chúng khi chạy nếu bạn cần).

+0

Từ điển có thể tốt, nhưng nó phải là một từ điển 'Dictionary ' hoặc một cái gì đó khác như 'Dictionary ', hoặc 'Dictionary ', với một định nghĩa phù hợp loại nhà máy ngoại lệ (và giao diện, nếu có) được định nghĩa ở đâu đó. Việc ném một đối tượng Exception hiện có sẽ tối thiểu phá hủy dấu vết stack. Nếu hai luồng cả hai gặp phải cùng một loại ngoại lệ cùng một lúc, việc chia sẻ một đối tượng ngoại lệ giữa chúng có thể làm cho trình xử lý của một luồng để xem dấu vết ngăn xếp của luồng khác. – supercat

+0

Vâng, không phải là ví dụ tốt nhất về việc sử dụng từ điển cho điều đó. Nếu bất cứ điều gì bạn cần có thể lưu trữ các loại ngoại lệ, và không phải là ngoại lệ thực tế chính nó. – kemiller2002

+0

Thật không may, việc lưu trữ kiểu ngoại lệ không phải là hữu ích cho nhiều, vì trừ khi người ta sử dụng Reflection (một mệnh đề hơi dodgy trong bối cảnh của một ngoại lệ), không có cách tổng quát, cho một kiểu ngoại lệ, tạo ra một ngoại lệ loại đó. – supercat

12

Tại sao không?

Từ Ngôn ngữ lập trình C#, Ed thứ ba. bởi Anders Hejlsberg et al, trang 362:

Danh sách tuyên bố của một bộ phận công tắc thường kết thúc bằng một, goto case, hoặc goto default tuyên bố break, nhưng bất kỳ cấu trúc đó ám chỉ rằng điểm kết thúc của danh sách tuyên bố không thể truy cập được phép . [...] Tương tự, câu lệnh throw hoặc return luôn chuyển quyền kiểm soát ở nơi khác và không bao giờ đạt đến điểm kết thúc.Như vậy ví dụ sau đây là hợp lệ:

switch(i) { 
case 0: 
    while(true) F(); 
case 1: 
    throw new ArgumentException(); 
case 2: 
    return; 
} 
0

Tôi không thấy bất kỳ vấn đề với việc sử dụng một chuyển đổi trong trường hợp của bạn.

Việc cân nhắc mạnh mẽ hơn nên đi đến việc liệu các ngoại lệ có phù hợp hay không. Nói chung, ngoại lệ chỉ nên được sử dụng khi tình huống phát sinh ngoài phạm vi hành vi dự kiến. Các ngoại lệ không nên được sử dụng làm logic luồng chương trình. Trong trường hợp của bạn, bạn có thể không được sử dụng chúng dựa trên mã tôi thấy.

0

Có lẽ tôi xin trân trọng khác với tất cả các câu trả lời ở đây ..

Thay vì phải chuyển đổi trong các mã, tôi thà vượt qua trong các result đến lớp ClientException & để cho nó quyết định những gì chuỗi nó cần để hiển thị thay vì sau đó có một công tắc xấu xí khắp nơi để tạo ra các thông điệp khác nhau

mã của tôi sẽ như thế nào:

throw new ClientException(result, cTbx.Text); 

Vì vậy, ngay cả khi bạn có thể ném sai sót trong switch...case, bạn có thể tránh tất cả là mất của tôi

+1

Tại thời điểm đó, hàm tạo ClientException sẽ có cùng một logic chuyển đổi, nhưng nó sẽ phải có ngắt. – Yishai

+0

hoặc nếu ... else :) – Sunny

+0

Tôi đã bỏ phiếu vì giải pháp "" này chỉ thay đổi vấn đề. Điều này không tạo ra bất kỳ sự khác biệt thực sự nào. –

Các vấn đề liên quan