2009-10-08 28 views
6

Từ MSDN:Có bao giờ một lý do cho việc ném một ngoại lệ từ một chuyển đổi ngầm không?

Bằng cách loại bỏ các phôi không cần thiết, chuyển đổi ngầm có thể cải thiện khả năng đọc mã nguồn. Tuy nhiên, bởi vì các chuyển đổi tiềm ẩn có thể xảy ra mà không có sự chỉ định của người lập trình, việc chăm sóc phải được thực hiện để ngăn chặn những bất ngờ khó chịu. Nói chung, các nhà khai thác chuyển đổi tiềm ẩn không bao giờ nên ném ngoại lệ và không bao giờ mất thông tin để chúng có thể được sử dụng một cách an toàn mà không có sự nhận thức của người lập trình. Nếu một nhà điều hành chuyển đổi không thể đáp ứng các tiêu chí đó, nó phải được đánh dấu rõ ràng.

Mặc dù tôi không đồng ý với bất kỳ điểm cụ thể nào và tôi đồng ý rằng điều này rất tốt, có lý do nào đủ lớn để đảm bảo vi phạm phần chuyển đổi tiềm ẩn không ném ngoại lệ không?

Các trường hợp cụ thể tôi đã nói rồi tôi là một trong những nơi:

  1. Tôi có một chức năng, mà trả về một đối tượng sưu tập tùy chỉnh (chúng tôi sẽ gọi nó là FooCollection).
  2. Chức năng này có thể trả lại các bộ sưu tập với một mục duy nhất và nó có thể được xác định từ mã nguồn cho dù điều này có xảy ra hay không. (bằng cách này, tôi có nghĩa là chỉ gọi hàm, chứ không phải chính hàm)
  3. Nếu điều đó xảy ra, có khả năng người dùng muốn có một mục duy nhất là 99,9% chứ không phải là một tập hợp với một mục duy nhất.

Bây giờ, tôi đang tung lên xem có nên bao gồm một chuyển đổi ngầm từ FooCollection =>Foo để ẩn ít chi tiết thực hiện điều này, nhưng chuyển đổi này sẽ chỉ làm việc nếu có một mục duy nhất trong bộ sưu tập.

Bạn có muốn ném một số Exception trong trường hợp này không? Hoặc tôi có nên sử dụng dàn diễn viên rõ ràng thay thế không? Bất kỳ ý tưởng khác về cách tôi có thể đối phó với điều này (không, do chi tiết thực hiện tôi không thể chỉ sử dụng hai chức năng)?

EDIT: tôi cảm thấy nó xứng đáng với lưu ý rằng FooCollection không thực hiện bất kỳ giao diện hoặc thực sự mở rộng Collection như tên gọi có thể hàm ý, vì thế mà câu trả lời LINQ dựa là vô ích. Ngoài ra, trong khi bộ sưu tập thực hiện một chỉ mục số, nó không phải là cách trực quan nhất để giải quyết bộ sưu tập vì nó dựa vào chỉ mục có tên chủ yếu.

Trả lời

10

Tôi có hướng dẫn: Bạn không bao giờ nên ném từ một chuyển đổi tiềm ẩn.

Tôi chắc chắn sẽ không cung cấp chuyển đổi tiềm ẩn trong trường hợp này. Ngay cả ý tưởng của một diễn viên rõ ràng cảm thấy sai với tôi: Foo x = (Foo)fooCollection dường như không đúng.

Tại sao bạn không để mã gọi điện thoại lo lắng về việc chuyển đổi từ FooCollection sang Foo? Mã sẽ trực quan hơn nhiều đối với mọi người:

Foo a = fooCollection[0]; 
Foo b = fooCollection.First(); 
Foo c = fooCollection.FirstOrDefault(); 
// etc 
+0

'Foo x = (Foo) fooCollection' sẽ không được 'đúng' hoặc (mặc dù nó sẽ biên dịch). 'Foo x = (Foo) fooCollection.x()' sẽ là cách nó sẽ được sử dụng. –

+0

x() là hàm trả về một tập con của 1 mục từ fooCollection. –

+0

Cũng vui lòng xem chỉnh sửa của tôi trong câu hỏi. –

0

Dàn diễn viên phải rõ ràng. Sẽ rất lạ khi có thể chỉ định một số FooCollection cho một số Foo mà không có ít nhất một dàn diễn viên.

Điều đó đang được nói, IMHO phôi không phải là một cách hay để thực hiện việc này. Ngay cả khi bạn nói không với nó, tôi sẽ sử dụng một hàm bởi vì ngay cả khi bạn không có quyền kiểm soát việc triển khai các lớp này, bạn cũng có thể thêm ít nhất Phương thức mở rộng như Foo ToFoo(this FooCollection collection) để hoàn thành công việc.

+0

Tôi thực sự chắc chắn 50% sẽ không hoạt động vì đây là trong ngữ cảnh của C# 4.0 và các loại động –

+0

tức là. Tôi không chắc liệu định tuyến động có tính đến phương pháp mở rộng tài khoản hay không. Dang nó, bây giờ tôi có cái gì khác tôi muốn thử! –

0

Một sự đồng ý ngầm chỉ hoạt động nếu chỉ có 1 mục trong bộ sưu tập? Vì vậy, trên thực tế, nó không hoạt động phần lớn thời gian?

Tôi sẽ không bao giờ thực hiện chuyển đổi này ẩn. Stick với rõ ràng. Nếu lập trình viên sử dụng hàm của bạn muốn có một mục duy nhất, anh ta chỉ nên nói cho lớp của bạn biết.

1

Rõ ràng là không ổn. Không bao giờ bao giờ sử dụng ngoại lệ để thực hiện logic!

Bạn có thể sử dụng LINQ-Statement FooCollection.FirstOrDefault(), sẽ cung cấp giá trị null hoặc mục đầu tiên.

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