2010-08-12 51 views

Trả lời

54

Trong Java, bạn phải xử lý ngoại lệ hoặc đánh dấu phương thức là một phương thức có thể ném nó bằng cách sử dụng từ khóa throws.

C# không có từ khóa này hoặc từ khóa tương đương, như trong C#, nếu bạn không xử lý ngoại lệ, nó sẽ bong bóng lên, cho đến khi bị bắt hoặc nếu không bị bắt, nó sẽ chấm dứt chương trình.

Nếu bạn muốn xử lý nó sau đó lại ném bạn có thể làm như sau:

try 
{ 
    // code that throws an exception 
} 
catch(ArgumentNullException ex) 
{ 
    // code that handles the exception 
    throw; 
} 
+0

@Louis RH - Tôi hiểu. Không có C# (hoặc .NET) tương đương. – Oded

+0

"nó sẽ bong bóng lên", điều này có nghĩa rằng điều này là tương đương với tất cả các phương pháp có một khoản ném trong Java? –

+1

@Louis RH - loại. Nó có nghĩa là một ngoại lệ, nếu không được xử lý, sẽ đi lên chuỗi cuộc gọi thông qua mỗi chức năng gọi điện thoại cho đến khi xử lý. – Oded

1

Bạn đang hỏi về vấn đề này:

lại ném một ngoại lệ

public void Method() 
{ 
    try 
    { 
     int x = 0; 
     int sum = 100/x; 
    } 
    catch(DivideByZeroException e) 
    { 
     throw; 
    } 
} 

hoặc

static void Main() 
    { 
     string s = null; 

     if (s == null) 
     { 
      throw new ArgumentNullException(); 
     } 

     Console.Write("The string s is null"); // not executed 
    } 
+2

+1 để sử dụng 'throw'. Bằng cách sử dụng nó, dấu vết ngăn xếp sẽ không bị mất. –

14

Dưới đây là một câu trả lời cho một câu hỏi tương tự Tôi chỉ quỹ trên bytes.com:

Câu trả lời ngắn gọn là không, có được không kiểm tra trường hợp ngoại lệ trong C#. Các nhà thiết kế của ngôn ngữ thảo luận về quyết định này trong cuộc phỏng vấn này:

http://www.artima.com/intv/handcuffs.html

gần nhất bạn có thể nhận được là sử dụng các thẻ trong tài liệu XML của bạn, và phân phối NDoc tạo tài liệu với mã của bạn/hội để rằng những người khác có thể thấy ngoại lệ nào bạn ném (đó chính xác là những gì MS thực hiện trong tài liệu MSDN). Bạn không thể dựa vào trên trình biên dịch để cho bạn biết về các ngoại lệ chưa được xử lý, tuy nhiên, như bạn có thể được sử dụng trong java.

2

Thực tế không có ngoại lệ được kiểm tra trong C# có thể được coi là điều tốt hay xấu.

Bản thân tôi coi nó là một giải pháp tốt vì trường hợp ngoại lệ được kiểm tra cung cấp cho bạn các vấn đề sau:

  1. Exceptions kỹ thuật bị rò rỉ đến lớp kinh doanh/miền vì bạn không thể xử lý đúng trên mức thấp.
  2. Chúng thuộc về chữ ký phương thức không phải lúc nào cũng đẹp với thiết kế API.

Do đó trong hầu hết các ứng dụng lớn hơn, bạn sẽ thấy mô hình sau đây thường khi Exceptions kiểm tra xảy ra:

try { 
    // Some Code 
} catch(SomeException ex){ 
    throw new RuntimeException(ex); 
} 

Mà về cơ bản có nghĩa là bắt chước cách C#/NET xử lý tất cả các trường hợp ngoại lệ..

+0

Tôi không thể tưởng tượng được các ngoại lệ được kiểm tra sẽ kết hợp với lambdas như thế nào! – Gabe

+0

@Gabe: Tôi chắc rằng bạn có thể đưa ra một số khái niệm cho phép bạn trộn chúng, nhưng như tôi đã nói, kiểm tra ngoại lệ trong Java cũng hầu như không thực hành tốt, đặc biệt là trong các ứng dụng phức tạp hơn. Vì vậy, nó tốt họ không có trong C#. –

67

Câu hỏi đang hỏi về số C# tương đương với số throws clause của Java - không phải là từ khóa throw. Điều này được sử dụng trong các chữ ký phương thức trong Java để chỉ ra một ngoại lệ đã kiểm tra có thể được ném ra.

Trong C#, không có tương đương trực tiếp của ngoại lệ được kiểm tra Java. C# không có mệnh đề chữ ký phương thức tương đương.

// Java - need to have throws clause if IOException not handled 
public void readFile() throws java.io.IOException { 
    ...not explicitly handling java.io.IOException... 
} 

dịch để

// C# - no equivalent of throws clause exceptions are unchecked 
public void ReadFile() 
{ 
    ...not explicitly handling System.IO.IOException... 
} 
12

Có điều này là một chủ đề cũ, tuy nhiên tôi thường xuyên tìm thấy chủ đề cũ khi tôi googling câu trả lời vì vậy tôi figured tôi sẽ thêm một cái gì đó hữu ích mà tôi đã được tìm thấy.

Nếu bạn đang sử dụng Visual Studio 2012, có một công cụ tích hợp có thể được sử dụng để cho phép mức tương đương "ném" IDE.

Nếu bạn sử dụng XML Documentation Comments, như đã đề cập ở trên, thì bạn có thể sử dụng thẻ <exception> để chỉ định loại ngoại lệ được ném bởi phương pháp hoặc lớp cũng như thông tin về thời điểm hoặc lý do được ném.

dụ:

/// <summary>This method throws an exception.</summary> 
    /// <param name="myPath">A path to a directory that will be zipped.</param> 
    /// <exception cref="IOException">This exception is thrown if the archive already exists</exception> 
    public void FooThrowsAnException (string myPath) 
    { 
     // This will throw an IO exception 
     ZipFile.CreateFromDirectory(myPath); 
    } 
+2

OP, đây là câu trả lời của bạn. Tôi đoán, nhưng 'ném' của JAVA có thể có nghĩa là không có gì trong thời gian chạy, ngoài việc cung cấp thông tin cho nhà phát triển. Tương tự như vậy, những gì @ mvanella chỉ ra ở đây là cách của C# để làm chính xác như vậy. Tôi giả sử bạn đã biết rằng "tài liệu xml" này có mục đích quan trọng hơn. Tôi biết chủ đề này là cũ. –

2

Có một số điểm tương đồng phù du giữa Net CodeContract EnsuresOnThrow<> và mô tả java throws, trong đó cả hai có thể là dấu hiệu để người gọi như kiểu của ngoại lệ có thể được huy động từ một hàm hoặc phương pháp, mặc dù cũng có những khác biệt lớn giữa 2:

  • EnsuresOnThrow<> vượt xa chỉ cần nêu được trường hợp ngoại lệ có thể được ném ra, nhưng cũng quy định các điều kiện theo đó họ gua để được ném - điều này có thể là mã khá hợp lý trong phương thức được gọi nếu điều kiện ngoại lệ không phải là tầm thường để xác định. Java throws cung cấp dấu hiệu cho thấy ngoại lệ nào có thể được ném (tức là IMO tập trung vào .Net nằm trong phương thức hợp đồng để chứng minh throw, trong khi ở Java trọng tâm chuyển sang người gọi để xác nhận khả năng ngoại lệ).
  • Net CC không làm cho sự phân biệt giữa Checked vs Unchecked ngoại lệ rằng Java có, mặc dù CC thủ công phần 2.2.2 không đề cập đến

"sử dụng postconditions đặc biệt chỉ dành cho những trường hợp ngoại lệ mà một người gọi nên mong đợi như một phần của API"

  • trong Net người gọi có thể xác định có hay không để làm bất cứ điều gì ngoại trừ (ví dụ bằng cách vô hiệu hóa hợp đồng). Trong Java, người gọi must do something, ngay cả khi nó thêm throws cho cùng một ngoại lệ trên giao diện của nó.

Code Contracts manual here

1

Sau khi đi qua hầu hết các câu trả lời ở đây, tôi muốn thêm một vài suy nghĩ.

  1. Dựa vào tài liệu XML Nhận xét và mong đợi người khác dựa vào là lựa chọn không tốt. Hầu hết mã C# mà tôi đã gặp không phải là phương pháp tài liệu hoàn toàn và nhất quán với các chú thích tài liệu XML. Và sau đó có vấn đề lớn hơn mà không có ngoại lệ được kiểm tra trong C#, làm thế nào bạn có thể ghi lại tất cả các ngoại lệ mà phương thức của bạn ném cho mục đích người dùng API của bạn biết cách xử lý tất cả các cá nhân? Hãy nhớ rằng, bạn chỉ biết về những người bạn tự ném mình với từ khóa ném trong việc triển khai của bạn. Các API bạn đang sử dụng bên trong triển khai phương pháp của mình cũng có thể ném ngoại lệ mà bạn không biết vì chúng có thể không được ghi lại và bạn không xử lý chúng trong quá trình triển khai của mình, vì vậy chúng sẽ xuất hiện khi người gọi phương pháp. Nói cách khác, các chú thích tài liệu XML này không thay thế cho các ngoại lệ đã kiểm tra.

  2. Andreas đã liên kết cuộc phỏng vấn với Anders Hejlsberg trong câu trả lời ở đây về lý do tại sao nhóm thiết kế C# quyết định chống lại ngoại lệ đã kiểm tra. Câu trả lời cuối cùng cho câu hỏi ban đầu được ẩn trong cuộc phỏng vấn rằng:

các lập trình viên bảo vệ mã của họ bằng cách viết thử cuối cùng là ở khắp mọi nơi, vì vậy họ sẽ trở lại một cách chính xác nếu một ngoại lệ xảy ra, nhưng họ không thực sự quan tâm đến việc xử lý các ngoại lệ.

Nói cách khác, không ai nên quan tâm đến loại ngoại lệ nào có thể được mong đợi đối với một API cụ thể vì bạn luôn bắt tất cả chúng ở mọi nơi. Và nếu bạn thực sự quan tâm đến các trường hợp ngoại lệ cụ thể, cách xử lý chúng tùy thuộc vào bạn và không phải ai đó xác định chữ ký phương thức với một cái gì đó như Java ném từ khóa, buộc xử lý ngoại lệ cụ thể trên người dùng API.

-

Cá nhân, tôi bị rách tại đây. Tôi đồng ý với Anders rằng việc kiểm tra ngoại lệ không giải quyết được vấn đề mà không cần thêm các vấn đề mới, khác biệt. Cũng giống như với các bình luận tài liệu XML, tôi hiếm khi thấy mã C# với mọi thứ được gói trong khối thử cuối cùng. Nó cảm thấy với tôi mặc dù điều này thực sự là lựa chọn duy nhất của bạn và một cái gì đó mà có vẻ như một thực hành tốt.

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