ATUALIZAÇÃO: esta resposta foi escrita em 2011. Após duas décadas de pessoas propondo covariância de tipo de retorno para C #, parece que finalmente será implementado; Estou bastante surpreso. Consulte o final de https://devblogs.microsoft.com/dotnet/welcome-to-c-9-0/ para obter o anúncio; Tenho certeza de que os detalhes virão.
Parece que o que você quer é a covariância do tipo de retorno. C # não oferece suporte à covariância de tipo de retorno.
A covariância do tipo de retorno é onde você substitui um método de classe base que retorna um tipo menos específico por outro que retorna um tipo mais específico:
abstract class Enclosure
{
public abstract Animal Contents();
}
class Aquarium : Enclosure
{
public override Fish Contents() { ... }
}
Isso é seguro porque os consumidores de Conteúdo via Enclosure esperam um Animal, e o Aquarium promete não apenas cumprir esse requisito, mas, além disso, fazer uma promessa mais rígida: que o animal é sempre um peixe.
Esse tipo de covariância não é compatível com C # e provavelmente nunca será compatível. Não é compatível com o CLR. (É suportado por C ++ e pela implementação C ++ / CLI no CLR; ele o faz gerando métodos auxiliares mágicos do tipo que sugiro abaixo.)
(Algumas linguagens também suportam contravariância de tipo de parâmetro formal - que você pode substituir um método que pega um Peixe por um método que pega um Animal. Novamente, o contrato é cumprido; a classe base requer que qualquer Peixe seja manipulado, e o derivado classe promete não apenas lidar com peixes, mas qualquer animal. Da mesma forma, C # e o CLR não suportam contravariância de tipo de parâmetro formal.)
A maneira de contornar essa limitação é fazer algo como:
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() { ... }
}
Agora você obtém os benefícios de substituir um método virtual e obter uma digitação mais forte ao usar algo do tipo Aquarium em tempo de compilação.