Câu hỏi 1:
Có phải vì trả lại StreamReader mới (tên tệp); bên trong vòng lặp for? hoặc thực tế là bạn không cần một vòng lặp for trong trường hợp này?
Streamreader không có gì để làm với nó. Các anti-pattern xuất hiện vì một mâu thuẫn rõ ràng về ý định giữa foreach
và if
:
Mục đích của là foreach
gì?
Tôi giả sử câu trả lời của bạn sẽ giống như: "Tôi muốn liên tục thực thi một đoạn mã cụ thể"
Có bao nhiêu tệp bạn muốn xử lý?
Vì bạn chỉ có thể có một tên tệp cụ thể (bao gồm cả phần mở rộng) trong một thư mục cụ thể, điều này chứng tỏ rằng mã của bạn được dự định để tìm một tệp áp dụng.
Điều này cũng được xác nhận bởi thực tế là bạn đang trả lại một giá trị ngay lập tức. Bạn không thực sự quan tâm đến trận đấu thứ hai, ngay cả khi nó tồn tại.
Có tình huống đây không phải là một mô hình chống.
- Nếu bạn cũng tìm trong thư mục con (
Directory.GetFiles(".", SearchOption.AllDirectories)
), thì có thể tìm thấy nhiều hơn một tệp có cùng tên tệp (bao gồm cả phần mở rộng)
- Nếu bạn tìm tên tệp trùng khớp một phần (ví dụ: mọi tệp có tên bắt đầu bằng
"Test_"
hoặc mỗi "*.zip"
tệp.
Lưu ý rằng cả hai trường hợp này sẽ yêu cầu bạn thực sự xử lý nhiều kết quả khớp và do đó không trả về giá trị ngay lập tức.
Câu hỏi 2:
Để sửa ví dụ thứ hai, bạn có viết lại nó mà không có câu lệnh if hay không, và thay vào đó bao quanh StreamReader bằng một khối bắt thử và nếu nó ném FileNotFoundException, bạn có xử lý nó trong khối bắt phù hợp không?
Ngoại lệ là đắt tiền. Chúng không bao giờ nên được sử dụng thay cho logic dòng chảy thích hợp. Ngoại lệ là, như tên của họ cho thấy hoàn cảnh đặc biệt .
Vì lý do đó, bạn không nên loại bỏ if
.
Theo câu trả lời này trên SoftwareEngineering.SE :
Nói chung, việc sử dụng các ngoại lệ cho luồng điều khiển là một mô hình chống đối, với các trường hợp đáng chú ý là ngoại lệ ho và ngôn ngữ cụ thể.
Như một tóm tắt nhanh về lý do tại sao, nói chung, đó là một mô hình chống:
- Các ngoại lệ về bản chất là các tuyên bố GOTO tinh vi
- Do đó, lập trình với các ngoại lệ, dẫn đến khó đọc và hiểu mã hơn
- Hầu hết các ngôn ngữ đều có cấu trúc điều khiển hiện có được thiết kế để giải quyết vấn đề của bạn mà không sử dụng ngoại lệ
- Các lập luận về hiệu quả có xu hướng được đưa ra cho các trình biên dịch hiện đại, có xu hướng tối ưu hóa với giả định rằng các ngoại lệ không được sử dụng cho luồng điều khiển.
Đọc cuộc thảo luận tại wiki của Ward để biết thêm thông tin chuyên sâu.
Cho dù bạn cần bọc cái này trong một lần thử / bắt, phụ thuộc rất nhiều vào tình huống của bạn:
- Bạn có khả năng gặp phải tình trạng đua như thế nào?
- Bạn có thực sự có thể xử lý tình huống này không, hoặc bạn muốn vấn đề này nổi lên với người dùng vì bạn không biết cách xử lý.
Không có gì là vấn đề "luôn luôn sử dụng nó". Để chứng minh quan điểm của tôi:
Các nghiên cứu riêng biệt đã chứng minh rằng bạn sẽ ít bị thương hơn khi đội mũ bảo hiểm, kính bảo hộ và áo chống đạn.
Vậy tại sao tất cả chúng ta không đeo thiết bị an toàn này mọi lúc?
Câu trả lời đơn giản là vì có những hạn chế khi mặc chúng:
- Nó tốn tiền
- Nó làm cho chuyển động của bạn trở nên cồng kềnh hơn
- Nó có thể khá ấm để mặc nó.
Bây giờ chúng tôi đang nhận được ở đâu đó: có pro và nhược điểm . Nói cách khác, chỉ có ý nghĩa khi mặc thiết bị này trong trường hợp người chuyên nghiệp vượt trội hơn .
- Công nhân xây dựng có nhiều khả năng bị chấn thương trong công việc của họ. Họ được hưởng lợi từ một chiếc mũ bảo hiểm an toàn.
- Nhân viên văn phòng, mặt khác, có khả năng bị thương thấp hơn nhiều. Mũ bảo hiểm không đáng
- Một thành viên nhóm SWAT có nhiều khả năng bị bắn hơn, so với một nhân viên văn phòng.
Bạn có nên kết thúc cuộc gọi trong một thử / bắt? Điều đó phụ thuộc rất nhiều vào việc lợi ích của việc đó có vượt quá chi phí thực hiện hay không.
Lưu ý rằng những người khác có thể lập luận rằng chỉ cần một vài lần nhấn phím để bọc nó, vì vậy rõ ràng nó nên được thực hiện. Nhưng đó không phải là toàn bộ lập luận:
- Bạn cần phải quyết định phải làm gì khi bạn bắt được ngoại lệ.
- Nếu có rất nhiều lệnh gọi khác nhau đến các tệp khác nhau trên toàn bộ cơ sở mã, việc quyết định gói một trong một lần thử / bắt thường có nghĩa là bạn phải bọc tất cả các trường hợp này. Điều này có thể có một tác động mạnh mẽ đến số lượng nỗ lực cần thiết để thực hiện nó.
- Nó hoàn toàn có thể là bạn cố ý muốn không xử lý một ngoại lệ.
- Lưu ý rằng ứng dụng của bạn sẽ phải xử lý ngoại lệ tại một số điểm, nhưng điều đó không nhất thiết ngay lập tức sau khi ngoại lệ được nêu ra.
Vì vậy, sự lựa chọn là của bạn. Có một lợi ích để làm như vậy? Bạn có nghĩ rằng nó cải thiện ứng dụng, hơn cả chi phí nỗ lực để thực hiện nó không?
Cập nhật - Từ một bình luận tôi đã viết cho câu trả lời khác, vì tôi nghĩ đó cũng là một sự cân nhắc phù hợp với bạn:
Nó rất nhiều bản lề về bối cảnh xung quanh.
- Nếu việc mở bộ đọc luồng được đi trước
if(!File.Exists) File.Create()
, thì sự vắng mặt của tệp khi mở bộ đọc luồng thực sự là đặc biệt .
- Nếu tên tệp được chọn từ danh sách các tệp hiện có, sự vắng mặt đột ngột của nó lại là ngoại lệ .
- Nếu bạn đang làm việc với một chuỗi mà bạn chưa thực sự kiểm tra thư mục; sau đó sự vắng mặt của tập tin là một kết quả hoàn toàn hợp lý, và do đó không phải là ngoại lệ .