CẬP NHẬT: Câu trả lời này được viết vào năm 2011. Sau hai thập kỷ mọi người đề xuất hiệp phương sai kiểu trả về cho C #, có vẻ như nó cuối cùng sẽ được thực hiện; Tôi khá ngạc nhiên. Xem phần cuối của https://devblogs.microsoft.com/dotnet/welcome-to-c-9-0/ để biết thông báo; Tôi chắc chắn chi tiết sẽ theo sau.
Có vẻ như những gì bạn muốn là hiệp phương sai kiểu trả về. C # không hỗ trợ hiệp phương sai kiểu trả về.
Hiệp phương sai kiểu trả về là nơi bạn ghi đè phương thức lớp cơ sở trả về kiểu ít cụ thể hơn với phương thức trả về kiểu cụ thể hơn:
abstract class Enclosure
{
public abstract Animal Contents();
}
class Aquarium : Enclosure
{
public override Fish Contents() { ... }
}
Điều này là an toàn vì người tiêu dùng Nội dung thông qua Bao vây mong đợi một Động vật và Thủy cung hứa hẹn không chỉ đáp ứng yêu cầu đó mà hơn thế nữa, thực hiện một lời hứa nghiêm ngặt hơn: rằng động vật luôn là cá.
Loại hiệp phương sai này không được hỗ trợ trong C # và không bao giờ được hỗ trợ. Nó không được hỗ trợ bởi CLR. (Nó được hỗ trợ bởi C ++ và bởi việc triển khai C ++ / CLI trên CLR; nó làm như vậy bằng cách tạo ra các phương thức trợ giúp kỳ diệu thuộc loại mà tôi đề xuất bên dưới.)
(Một số ngôn ngữ cũng hỗ trợ sự đối nghịch kiểu tham số chính thức - bạn có thể ghi đè phương thức lấy Cá bằng phương thức lấy Động vật. Một lần nữa, hợp đồng được thực hiện; lớp cơ sở yêu cầu mọi Cá được xử lý và dẫn xuất lớp hứa hẹn không chỉ xử lý cá, mà còn bất kỳ động vật nào. Tương tự, C # và CLR không hỗ trợ sự đối nghịch kiểu tham số chính thức.)
Cách bạn có thể khắc phục hạn chế này là làm một số việc như:
abstract class Enclosure
{
protected abstract Animal GetContents();
public Animal Contents() { return this.GetContents(); }
}
class Aquarium : Enclosure
{
protected override Animal GetContents() { return this.Contents(); }
public new Fish Contents() { ... }
}
Giờ đây, bạn nhận được cả lợi ích của việc ghi đè một phương thức ảo và gõ mạnh hơn khi sử dụng Aquarium loại thời gian biên dịch.