Tôi đồng ý với @MartinMaat về việc chọn các trận đánh của bạn.
Có nhiều trường hợp "chỉ trong trường hợp" do không thực sự hiểu ngôn ngữ mặc dù ngôn ngữ đã được cố định trong các quy tắc của nó đối với nhiều điều này - qua việc ngoặc đơn một biểu thức không cần nó do không hiểu các quy tắc ưu tiên của ngôn ngữ. Tuy nhiên, thực tế như vậy chủ yếu là vô hại.
Khi tôi còn trẻ, tôi cảm thấy rằng chúng ta nên tìm hiểu các chi tiết của ngôn ngữ và do đó tránh viết mã không cần thiết như vậy. (Một trong những thú cưng của tôi-Peeves là return (0);
với dấu ngoặc không cần thiết của nó.) Tuy nhiên, bây giờ tôi vừa vị trí đó, đặc biệt, bởi vì chúng tôi sử dụng rất nhiều ngôn ngữ khác nhau bây giờ, nhảy từ client tới server, vv ... Vì vậy, bây giờ tôi cắt một số chùng cho một số vấn đề như vậy.
Bạn đang nói về cyclomatic bắt đầu đi đến tranh luận hợp lý. Hãy xem Bảo hiểm Mã và đặc biệt là mức độ bao phủ cao hơn :
- Mỗi quyết định có mọi kết quả có thể
Vì chúng tôi không thể buộc hoạt động mới trả về NULL, không có cách nào để đạt được mức độ bao phủ mã cao hơn cho hoạt động có điều kiện này. Tất nhiên, điều này có thể hoặc không quan trọng đối với tổ chức của bạn!
Tuy nhiên, vì vấn đề bảo hiểm mã này, tôi sẽ ưu tiên nó cao hơn so với quá ngoặc đơn.
Mặt khác, mã được tạo bên dưới có thể sẽ không chịu một chút nào cho điều này vì các thế hệ mã, JIT và trình tối ưu hóa đều hiểu rằng new
giá trị ed sẽ không bao giờ là null. Vì vậy, chi phí thực tế chỉ đến về khả năng đọc và khả năng bao phủ mã nguồn.
Tôi sẽ hỏi bạn "phần khác" của câu lệnh if như thế nào?
Nếu không có phần nào khác, tôi sẽ lập luận rằng chỉ cần rơi khỏi phần cuối của thói quen hoặc chuyển sang mã khác (nghĩa là không có else
phần này if
) là rất nguy hiểm, vì bây giờ điều này "chỉ trong trường hợp" gợi ý rằng người gọi và / hoặc thêm mã xuống dòng xử lý NULL là tốt.
Nếu nó đọc:
p = new Object ();
if ( p != null ) {
p.field = value;
}
else {
throw new NullReferenceException ();
}
thì điều này thực sự quá mức cần thiết, vì ngôn ngữ làm tất cả những điều đó cho chúng ta.
Tôi có thể đề nghị đảo ngược ý nghĩa của điều kiện - có lẽ đồng nghiệp của bạn sẽ thoải mái hơn với điều này:
p = new Object ();
if ( p == null ) {
throw new NullReferenceException ();
}
else {
p.field = value;
}
Bây giờ bạn có thể tranh luận về việc loại bỏ trình bao bọc khác, vì nó rất rõ ràng không cần thiết:
p = new Object ();
if ( p == null ) {
throw new NullReferenceException ();
}
p.field = value;
Với điều này, "chỉ trong trường hợp" bây giờ là những gì có điều kiện, trong khi mã thành công thì không. Cách tiếp cận này củng cố thêm rằng khi phân bổ thất bại, phản hồi thích hợp sẽ được đưa ra, thay vì tiếp tục chạy mã trong phương thức này và / hoặc trong chuỗi cuộc gọi này (mà không có bất kỳ xử lý thích hợp nào khác đối với lỗi phân bổ).
Vì vậy, tóm lại, có hai lý lẽ hợp lý để đưa ra ở đây chống lại thực tiễn này:
- Mức độ bao phủ mã cao hơn không thể đạt được vì chúng ta không thể buộc hết bộ nhớ (hoặc bất kỳ lỗi xây dựng nào) để trả về null.
- "Chỉ trong trường hợp" (như được hiển thị ở trên trong câu hỏi) là không đầy đủ và như vậy là thiếu sót vì sự không nhất quán trong kỳ vọng về cách null được xử lý bởi các mã khác ngoài / quá khứ
p.field = value;
.
Về cơ bản, có vẻ như có lẽ đồng nghiệp của bạn đang ở trong hàng rào về việc sử dụng các ngoại lệ - mặc dù C # không có lựa chọn nào ở đây cho những điều như vậy. ( Nếu chúng tôi muốn mã được kiểm tra tốt, chúng tôi không thể mã cho cả mô hình ngoại lệ để xử lý null và mô hình không ngoại lệ bằng cách sử dụng giá trị null-return-side, side-side.) Có lẽ nếu bạn lý luận với đồng nghiệp của mình thông qua các chủ đề này, họ sẽ thấy một chút ánh sáng!