2015-05-06 20 views
14

Sau khi đọc this question hỏi chính xác những gì một “Special Class” được, tôi lại với câu hỏi tại sao trong sáu lớp System.Object, System.Array, System.Delegate, System.EnumSystem.ValueType đã được lựa chọn và hard-coded lớp như đặc biệt, ngăn không cho chúng khỏi bị sử dụng như những hạn chế để các lớp hoặc phương thức chung.Tại sao chính xác những "Lớp học đặc biệt" này?

Có thể hiểu được lý do tại sao System.Object ở trong đó; tất cả các lớp kế thừa System.Object do đó không cần phải bao gồm nó như một ràng buộc. Những gì tôi không rõ ràng là lý do tại sao những người khác đã được chọn là một phần của thể loại lớp học đặc biệt này.

PS: Các lớp đặc biệt làm tăng lỗi biên dịch CS0702 khi cố gắng sử dụng chúng làm hạn chế.

+1

Tất cả những người khác là gốc rễ của cây thừa kế không điển hình có hỗ trợ ngôn ngữ đặc biệt để sử dụng. –

+0

@Damien_The_Unbeliever: Đủ công bằng. Tôi muốn chỉ ra rằng có những trường hợp điển hình trong đó một số ràng buộc này có thể hữu ích. Lấy ví dụ, một phương thức yêu cầu các đối số là kiểu 'Enum'. Bằng cách hạn chế này, việc viết một phương thức chung với một ràng buộc 'Enum' là không thể trừ khi người ta muốn sử dụng các cách giải quyết như Jon Skeet được sử dụng trong [Melody không bị giới hạn] (https://github.com/jskeet/unconstrained-melody). Phải thừa nhận rằng, không phải ai cũng có kỹ năng để thực hiện các giải pháp này ngay cả khi họ có lý do chính đáng để muốn sử dụng bất kỳ "Lớp học đặc biệt" nào làm hạn chế. –

+0

Tôi nghĩ rằng họ không lường trước được nhiều việc sử dụng cho các loại này trong generics (mặc dù tôi đồng ý tôi muốn làm chúng với enums nhiều hơn một lần) và tôi nghĩ rằng trong thay thế, bạn sẽ phải thực hiện rất nhiều quy tắc nếu bạn đã cho phép chúng - nghĩa là bạn vẫn phải đối xử với chúng đặc biệt vì ví dụ 'ValueType' là một kiểu tham chiếu nhưng tất cả các cá thể thực tế xuất phát từ nó là các kiểu giá trị. –

Trả lời

7

Các lớp đó đã khác trước các ràng buộc chung chung, hoặc thậm chí là generics, đã được thêm vào khuôn khổ .NET và hỗ trợ cho chúng được thêm vào ngôn ngữ C#.

gì mỗi người trong số họ có điểm chung, đó là kế thừa từ họ là khác nhau hơn so với các loại khác:

System.Object: Bạn không thể không kế thừa từ này trong C#.

System.Array: Bạn thừa hưởng từ này bằng cách tạo một mảng của một loại hiện có (Array x = new int[2];, vv)

System.Delegate: Bạn thừa hưởng từ này bằng cách tạo một delegate (mà sau đó xuất phát từ MulticastDelegate, cũng là một "loại đặc biệt", có nguồn gốc từ Delegate).

System.Enum: Bạn kế thừa từ điều này bằng cách tạo enum.

System.ValueType: Bạn kế thừa từ điều này bằng cách tạo struct.

Bây giờ, lưu ý rằng ngoài new() ràng buộc chung là tất cả về kế thừa hoặc thực hiện giao diện (tương tự như thừa kế theo nhiều cách). Thật vậy, các hạn chế khác là bạn không thể sử dụng một kiểu con trỏ, và bạn không thể sử dụng một loại kín; hai trường hợp mà bạn không thể có một kiểu dẫn xuất nào (mặc dù lệnh cấm trên các kiểu niêm phong chủ yếu là vì bạn có khả năng tạo một kiểu hoặc phương thức chung khi bạn không cần quá, và là một nỗ lực để bảo vệ bạn khỏi chính bạn) .

Và như mã như vậy dựa trên các tính năng thừa kế (như các ràng buộc) khi đối mặt với các trường hợp đặc biệt về kế thừa có thể sẽ phải liên quan đến các trường hợp đặc biệt. Những trường hợp đặc biệt đó được xử lý theo cách đơn giản nhất: Bằng cách cấm chúng.

Giá trị còn ít là trong rất nhiều các trường hợp:

System.Object: Kể từ khi loại duy nhất mà không thể được chuyển đổi sang System.Object là loại con trỏ, và những điều này không thể được sử dụng như các thông số chung nào , bất kỳ ràng buộc nào như vậy là thừa.

System.Array: Bạn có thể định nghĩa về các loại yếu tố: void DoSomethingWithArray<T>(T[] array), vv

System.Delegate: như vậy sẽ có ích, mặc dù trong nhiều trường hợp chúng ta có thể định nghĩa về tham số và/hoặc trả lại loại, nhưng có những trường hợp không bắt được.

System.Enum: Sẽ hữu ích.

System.ValueType: Đã được xử lý; hạn chế là struct. Ngược lại, chúng tôi cũng có thể hạn chế là class để loại trừ trường hợp này vì vậy chúng tôi đã thực sự là tùy chọn "không được kế thừa từ ..." mà chúng tôi không có.

Đây không phải là để phủ nhận rằng có khả năng hạn chế về mặt Delegate, MulticastDelegate hoặc Enum sẽ không có ích (có lẽ hầu hết vì vậy chúng tôi Enum), nhưng về mặt biện minh cho việc làm thêm để trang trải các loại những người khác sẽ cung cấp cho ít hoặc không có lợi ích, vì vậy lợi ích của ít hạn chế hơn là giảm.

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