AGGIORNAMENTO: Questa risposta è stata scritta nel 2011. Dopo due decenni di persone che hanno proposto la covarianza del tipo restituito per C #, sembra che sarà finalmente implementata; Sono piuttosto sorpreso. Vedere la parte inferiore di https://devblogs.microsoft.com/dotnet/welcome-to-c-9-0/ per l'annuncio; Sono sicuro che seguiranno i dettagli.
Sembra che quello che vuoi è la covarianza del tipo restituito. C # non supporta la covarianza del tipo restituito.
La covarianza del tipo restituito è il punto in cui si sostituisce un metodo di classe base che restituisce un tipo meno specifico con uno che restituisce un tipo più specifico:
abstract class Enclosure
{
public abstract Animal Contents();
}
class Aquarium : Enclosure
{
public override Fish Contents() { ... }
}
Questo è sicuro perché i consumatori di Contenuti tramite custodia si aspettano un animale e Aquarium promette non solo di soddisfare tale requisito, ma anche di fare una promessa più rigorosa: che l'animale è sempre un pesce.
Questo tipo di covarianza non è supportato in C # ed è improbabile che venga mai supportato. Non è supportato da CLR. (È supportato da C ++ e dall'implementazione C ++ / CLI su CLR; lo fa generando metodi di aiuto magico del tipo che suggerisco di seguito.)
(Alcuni linguaggi supportano anche la controvarianza del tipo di parametro formale: è possibile sovrascrivere un metodo che accetta un pesce con un metodo che accetta un animale. Anche in questo caso, il contratto è rispettato; la classe base richiede che qualsiasi pesce venga gestito e il derivato class promette di gestire non solo i pesci, ma qualsiasi animale. Allo stesso modo, C # e CLR non supportano la controvarianza del tipo di parametro formale.)
Il modo in cui puoi aggirare questa limitazione è fare qualcosa come:
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() { ... }
}
Ora ottieni sia i vantaggi di sovrascrivere un metodo virtuale, sia di ottenere una digitazione più forte quando usi qualcosa di tipo Aquarium in fase di compilazione.