Tôi quan tâm hơn đến câu trả lời từ điểm .Net và CLR của xem:Tại sao một Struct không thể bắt nguồn từ cấu trúc khác?
Tại sao cấu trúc không thể là lớp cơ sở của cấu trúc khác hoặc ngược lại?
Tôi quan tâm hơn đến câu trả lời từ điểm .Net và CLR của xem:Tại sao một Struct không thể bắt nguồn từ cấu trúc khác?
Tại sao cấu trúc không thể là lớp cơ sở của cấu trúc khác hoặc ngược lại?
Các đường ống chiếm các vị trí có kích thước cố định trong ngăn xếp (hoặc bất cứ nơi nào chúng đang sinh sống).
Do đó, bạn sẽ không thể thực hiện bất kỳ loại đa hình nào với cấu trúc, vì cấu trúc có nguồn gốc sẽ có kích thước khác.
Có thể kế thừa các thành viên từ các cấu trúc khác, nhưng vì bạn sẽ không thể thực hiện bất kỳ loại polymprphism nào, nó sẽ không đáng bị nhầm lẫn.
Trong .net, nếu lớp A
thừa hưởng từ loại B
và một đối tượng kiểu A
được chuyển sang mã mà hy vọng một đối tượng kiểu B
, đối tượng thông qua sẽ không được chuyển đổi sang một B
nhưng sẽ vẫn là một A
. Điều này là có thể bởi vì mọi đối tượng đã được lưu trữ với nó một tham chiếu đến một bộ mô tả kiểu. Các lớp không có bất kỳ kiểu mô tả nào được lưu trữ với chúng. Nếu một cấu trúc kiểu A
có thể được truyền theo giá trị cho một thường trình mong đợi một cấu trúc kiểu B
, nó sẽ trở thành một cấu trúc kiểu B
. Trong trường hợp đó sẽ là hợp lý, nó sẽ là thiết thực hơn để xác định một nhà điều hành chuyển đổi mở rộng từ loại A
đến B
.
Có những lúc có thể hữu ích khi chuyển cấu trúc loại A
bằng cách tham chiếu đến loại mong đợi định kỳ B
. Nhà điều hành chuyển đổi sẽ không trợ giúp ở đó. Tuy nhiên, điều đó có thể được xử lý, mặc dù hơi khó xử, bởi vì có kiểu cấu trúc A
không chứa gì ngoài một trường kiểu B
. Trường đó có thể được chuyển qua tham chiếu đến kiểu mong đợi thông thường B
; khó khăn sẽ là người ta phải bao gồm tên của cấu trúc bên trong trong bất kỳ trường truy cập nào.
Điều gì sẽ hữu ích, không chỉ cho cấu trúc mà còn cho các lớp học nữa, sẽ là khái niệm về 'loại tiện ích mở rộng'. Tất cả các lớp, dù là có thể kế thừa hay không, có thể được mở rộng với một kiểu mở rộng, chỉ bao gồm các thành viên cá thể; biến hoặc giá trị của loại tiện ích mở rộng sẽ được coi là đối tượng thời gian chạy của loại cơ sở và tất cả chuyển đổi giữa loại tiện ích và loại cơ sở hoặc giữa các loại tiện ích mở rộng có cùng loại cơ sở sẽ được coi là 'mở rộng' và được xử lý dưới dạng không có op. Hiệu ứng duy nhất của loại tiện ích mở rộng sẽ là đưa vào phạm vi thành viên được xác định cho loại đó. Chúng sẽ hoạt động giống như các phương thức mở rộng, ngoại trừ việc chúng sẽ chỉ áp dụng cho các biến và các biến được khai báo là kiểu mở rộng, và các thành viên của các kiểu mở rộng sẽ có ưu tiên hơn các thành viên lớp cơ sở. Người ta có thể tưởng tượng nhiều công dụng cho những thứ như vậy (trong trường hợp người ta muốn sử dụng các phương thức mở rộng trên một số cá thể của một lớp, nhưng có thể không muốn chúng có sẵn trên mọi trường hợp), nhưng chưa có ngôn ngữ nào tôi biết đặc tính.
Tuy nhiên, điều đó không loại trừ cú pháp khuôn mẫu, khi bạn được kế thừa từ một cấu trúc, bạn có một bản sao của tất cả các phương thức, thuộc tính và các trường của nó. Nó sẽ không được gán tương thích, nhưng nó sẽ có cùng một bố trí cộng với bất cứ thứ gì bạn thêm vào trong "hậu duệ". Tôi đoán rằng thực tế là đủ mặc dù, nó sẽ gây nhầm lẫn. –
Hai từ: đối tượng cắt. http://en.wikipedia.org/wiki/Object_slicing –
@ LasseV.Karlsen: Chính xác. Nếu được hỗ trợ, câu hỏi này sẽ là "Tại sao tôi không thể viết' Base b = new Derived() '?" – SLaks