2015-03-04 14 views
8

Giả sử tôi có thói quen sau đây:Delphi - Thứ tự "đúng" cho ngoại trừ và cuối cùng là khối là gì?

function ReadFile(f : TFilename) : Boolean; 
var 
    fs : TFileStream; 
begin 
    Result := False; 
    try 
    fs := TFileStream.Create(f, ...); 
    try 
     // read file ... 
     Result := True; 
    finally 
     FreeAndNil(fs); 
    end; 
    except 
    // handle exceptions ... 
    end; 
end; 

gì được ý nghĩa của việc có các exceptfinally hoán? Tôi đã thấy nhiều bài đăng với cả hai cách xung quanh, nhưng tôi chưa thấy giải thích rõ ràng về cách nào phù hợp trong trường hợp này (tôi vẫn nghĩ rằng trong cấu trúc trên, khối finally thực hiện sau số except khối!).

Tôi cũng thấy các bài đăng đề xuất rằng việc trộn các khối try..excepttry..finally không phải là một ý tưởng hay. Làm thế nào bạn có thể tránh nó trong các tình huống mà một thói quen ném một ngoại lệ như là một phần của hoạt động bình thường - chẳng hạn như trong một số thói quen Indy?

+3

* "trong cấu trúc trên, khối cuối cùng sẽ thực thi sau khối ngoại trừ" * - Điều đó không chính xác. –

Trả lời

11

Không có cách nào chính xác để viết điều này. Hai biến thể làm những việc khác nhau. Bạn có thể thích một phiên bản trong một kịch bản, một phiên bản khác trong một kịch bản khác.

Phiên bản 1, cuối cùng nội nhất

function ReadFile(f : TFilename) : Boolean; 
var 
    fs : TFileStream; 
begin 
    Result := False; 
    try 
    fs := TFileStream.Create(f, ...); 
    try 
     // read file ... 
     Result := True; 
    finally 
     FreeAndNil(fs); 
    end; 
    except 
    // handle exceptions ... 
    end; 
end; 

Phiên bản 2, cuối cùng bên ngoài-nhất

function ReadFile(f : TFilename) : Boolean; 
var 
    fs : TFileStream; 
begin 
    Result := False; 
    fs := TFileStream.Create(f, ...); 
    try 
    try 
     // read file ... 
     Result := True; 
    except 
     // handle exceptions ... 
    end; 
    finally 
    FreeAndNil(fs); 
    end; 
end; 

Sự khác biệt lớn là cách mã ứng xử nếu TFileStream.Create đặt ra một ngoại lệ, một sự kiện không hợp lý. Trong phiên bản 1, ngoại lệ sẽ bị bắt và xử lý bên trong ReadFile. Trong phiên bản 2, ngoại lệ sẽ được chuyển ra khỏi ReadFile và trên chuỗi các trình xử lý ngoại lệ.

Asides

Bạn trạng:

tôi vẫn nghĩ rằng đó là tò mò rằng trong cấu trúc trên, khối cuối cùng thực hiện sau khi trừ khối!

Điều đó không đúng đối với mã trong câu hỏi của bạn, phiên bản 1 ở trên. Có lẽ bạn chưa hoàn toàn hiểu được cách thức hoạt động của khối cuối cùng.

Sai lầm phổ biến thường được quan sát, là mong muốn nắm bắt và xử lý ngoại lệ càng sớm càng tốt. Đó là chiến lược sai lầm. Toàn bộ điểm về một ngoại lệ là nó không có nghĩa là xảy ra và bạn thường không biết phải làm gì khi nó xảy ra. Mục tiêu của bạn là xử lý các trường hợp ngoại lệ càng sớm càng tốt. Đối với đại đa số mã, bạn không nên xử lý các ngoại lệ. Hãy để chúng nổi lên tới một điểm trong mã có thể xử lý lỗi.

+0

Ok, tôi đoán tôi sai về thứ tự thực hiện. Tôi đã chắc chắn tôi đã thử nghiệm nó bằng cách bước qua một thói quen vì nó xử lý một ngoại lệ bị mắc kẹt, nhưng tôi đoán là không. Cảm ơn câu trả lời của bạn. Đẹp và kỹ lưỡng. – rossmcm

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