2013-06-06 24 views
11

Tôi có mảnh đơn giản mã này:Tôi nên làm gì khi buộc phải viết mã không thể truy cập?

public static int GetInt(int number) 
{ 
    int[] ints = new int[]{ 3, 7, 9, int.MaxValue }; 
    foreach (int i in ints) 
     if (number <= i) 
      return i; 

    return int.MaxValue; //this should be unreachable code since the last int is int.MaxValue and number <= int.MaxValue is allways true so the above code will allways return 
} 

Vấn đề là trình biên dịch nói rằng không phải mọi con đường thực hiện trả về một giá trị. Vì vậy, tôi phải viết mã mà sẽ không bao giờ đạt được. Câu hỏi của tôi là, tôi nên làm gì trong tình huống như thế này? Tôi có nên trả lại một số giá trị mặc định hay tôi nên ném một ngoại lệ. Ngoài ra, nếu tôi muốn ném một ngoại lệ, ngoại lệ nào phù hợp để ném? Tôi không tìm thấy bất kỳ thứ gì như UnreachableCodeException.

+1

Bạn có thể tuyên bố 'i' ra của 'foreach' và ngăn chặn tình trạng trên' số <= i' với một' break' , và sau đó bạn chỉ có một 'return' – MilkyWayJoe

Trả lời

22

tôi muốn được cám dỗ sử dụng InvalidOperationException - hoặc một số ngoại lệ khác mà bạn sẽ không bắt một cách rõ ràng. Cung cấp cho nó một thông điệp mà chỉ ra rằng bạn thực sự không mong đợi để có được ở đây. Đây là một "thế giới bị phá vỡ nghiêm trọng" thất bại. InvalidOperationException không hoàn toàn nắm bắt được điều này, nhưng tôi không thể nghĩ ra một điều tốt hơn. Bạn luôn có thể tạo ngoại lệ của riêng bạn để sử dụng trong toàn bộ codebase của bạn, tất nhiên.

Đừng chỉ trả về một giá trị, nếu không bạn sẽ không bao giờ tìm hiểu xem thế giới của bạn có bị lộn ngược hay không.

+0

Vì vậy, không có ngoại lệ .NET tích hợp cho mã không thể truy cập? Tôi không chắc chắn về việc sử dụng 'InvalidOperationException'. Không có bất kỳ ngoại lệ lỗi logic nào hay điều gì đó gần gũi hơn với vấn đề? – Bosak

+0

Trên một tound secound 'InvalidOperationException' là tốt khi tôi thấy những gì' IEnumerable.First() 'ném' InvalidOperationException' khi không có mục được tìm thấy. – Bosak

+1

@Bosak: Vâng, 'InvalidOperationException' có ý nghĩa hơn đối với' First' hơn so với trường hợp của bạn. Điều đó thực sự là gọi một phương thức khi nó không ở trạng thái hợp lệ - trong trường hợp của bạn, đó là điều bạn thực sự, thực sự không nghĩ là sẽ xảy ra. (Giả sử bạn đã biết rằng mảng không rỗng và chứa 'int.MaxValue'.) –

1

Trình biên dịch không thể biết rằng vòng lặp foreach của bạn sẽ luôn trả về giá trị.

Trình biên dịch lý thuyết có thể làm như vậy vì trong thông tin chính có sẵn, nhưng trình biên dịch C# không thể.

4

Tôi nghĩ mọi trường hợp đều khác nhau, nhưng có, cuối cùng bạn phải trả lại một cái gì đó hoặc ném một ngoại lệ. Cách xử lý này trong ví dụ mã của bạn chỉ là để loại bỏ int.MaxValue từ mảng của bạn:

public static int GetInt(int number) 
{ 
    int[] ints = new int[]{ 3, 7, 9 }; 
    foreach (int i in ints) 
     if (number <= i) 
      return i; 
    return int.MaxValue; 
} 
+0

tình hình phức tạp hơn một chút và tôi không thể sửa đổi bộ sưu tập – Bosak

5

Thay vì quay trở lại từ vòng lặp của bạn, hãy khai báo biến giá trị trả lại, đặt biến đó và sau đó trả lại một lần ở cuối mã.

public static int GetInt(int number) 
{ 
    var rtnVal = int.MaxValue; 
    int[] ints = new int[]{ 3, 7, 9, int.MaxValue }; 
    foreach (int i in ints) { 
     if (number <= i) { 
      rtnVal = i; 
      break; 
     } 
    } 
    return rtnVal; 
} 
2

Dưới đây là một lựa chọn LINQ tự động ném một ngoại lệ khi không phù hợp được tìm thấy

public static int GetInt(int number) 
{ 
    int[] ints = new int[]{ 3, 7, 9, int.MaxValue }; 
    return ints.First(i => number <= i); 
} 
+0

Hmm đẹp Tôi thích cách simetyc 'i => số <= i' trông: D – Bosak

8

Sử dụng sau để hiển thị một thông báo lỗi lôgic sau khi bạn foreach:

System.Diagnostics.Debug.Fail("Unreachable code reached"); 

chí này cảnh báo bạn trong khi gỡ lỗi.

Bên cạnh đó, cũng ném một ngoại lệ cho quá trình sản xuất:

throw new InvalidOperationException(); 

Đừng chỉ trả về một giá trị, đặc biệt là một trong đó là khả năng hợp lệ: bạn sẽ không bao giờ bắt lỗi logic.

+5

Sử dụng cả Debug.Fail và ngoại lệ là một ý tưởng hay; điều này gọi ra rằng ngoại lệ không có ý định thực sự là một đường dẫn mã thực thi. Tuy nhiên tôi muốn chọn một ngoại lệ tốt hơn so với 'ngoại lệ mới'. Jon đề xuất 'InvalidOperationException' có vẻ hợp lý. –

0

Tại sao không chỉ trả về giá trị đầu tiên mà lớn hơn số thay

public static int GetInt(int number) 
    { 
     var ints = new[] { 3, 7, 9}; 
     return (ints.Any(i => i > number))? 
      ints.First(i => i > number): int.MaxValue; 
    }