No, questa non è veramente covarianza. Questa è solo l'implementazione di un'interfaccia. In particolare, è un esempio di compatibilità di assegnazione . Poiché la classe Car
implementa l'interfaccia ICarInterface
, un oggetto Car
può essere assegnato a una variabile di tipo ICarInterface
. Un oggetto di un tipo più specifico (Car
) è stato assegnato a un'area di archiviazione per un tipo meno specifico (ICarInterface
), che funziona perché i due tipi sono compatibili ai fini dell'assegnazione.
La covarianza è una cosa leggermente diversa. Una relazione di tipo è covariante se conserva l'ordine dei tipi (dal più specifico al più generico). Ad esempio, IEnumerable<T>
è covariante rispetto al tipo T
, quindi conserva l'ordine dei tipi IEnumerable<Vehicle>
(più generico) e IEnumerable<Car>
(più specifico). (In questo esempio, assumiamo ovviamente che Car
sia una sottoclasse di Vehicle
).
Eric Lippert has written an excellent article that distinguishes between covariance and assignment-compatibility. Diventa leggermente tecnico e teorico, ma dovresti assolutamente leggerlo. Non lo farei giustizia cercando di sintetizzarlo ulteriormente qui.
Un esempio di covarianza più comprensibile (almeno secondo me) è la covarianza di tipo ritorno. È qui che l'override di una classe derivata di un metodo di classe base restituisce un tipo più specifico. Per esempio:
abstract class Habitat
{
public abstract Animal ApexPredator();
}
class Savanna : Habitat
{
public override Lion ApexPredator()
{ ... }
}
class Ocean : Habitat
{
public override Shark ApexPredator()
{ ... }
}
In questo esempio, la classe astratta Habitat
ha due sottoclassi concrete: Savanna
e Ocean
. Tutti gli habitat hanno un ApexPredator
, che è di tipo Animal
. Ma in un oggetto Savanna
, il predatore dell'apice è un Lion
, mentre in un oggetto Ocean
, il predatore dell'apice è un Shark
. Questo è legale e sicuro perché Lion
e Shark
sono entrambi i tipi di Animal
s.
Sfortunatamente, C# non supporta la covarianza del tipo di ritorno. È, tuttavia, supportato da C++ (incluso C++/CLI), Java e una serie di altri linguaggi orientati agli oggetti.
Eccone altri concrete examples of covariance.
No, questo non è. È legato ai generici. Ci sono un sacco di domande su SO già. – nawfal
Non capisco però, perché è strettamente correlato a Generics? Nel mio esempio, Car eredita da ICarInterface. Quindi non è il seguente un upcast implicito che significherebbe che è un esempio di Covariance? Cosa mi manca? ICarInterface car = new Car(); – Exocomp
Questo non è *** un duplicato. Exocomp sta chiedendo se * il codice specifico che mostra * è un esempio di covarianza (e perché/perché no), non per una grande lista di "esempi del mondo reale" di covarianza. Potrebbe * essere un duplicato di una domanda che spiega cos'è la covarianza, ma non è quella scelta. Riapertura ... –