La palabra clave out
en genéricos se utiliza para denotar que el tipo T en la interfaz es covariante. Vea Covariance and contravariance para más detalles.
El ejemplo clásico es IEnumerable<out T>
. Desde IEnumerable<out T>
es covariante, se le permite hacer lo siguiente:
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;
La segunda línea anterior fracasaría si esto no se covariante, a pesar de que lógicamente debería funcionar, ya que la cadena se deriva del objeto. Antes de agregar variance in generic interfaces a C# y VB.NET (en .NET 4 con VS 2010), esto era un error de tiempo de compilación.
Después de .NET 4, IEnumerable<T>
se marcó como covariante y se convirtió en IEnumerable<out T>
. Como IEnumerable<out T>
solo usa los elementos que contiene, y nunca los agrega ni los cambia, es seguro tratar una colección enumerable de cadenas como una colección enumerable de objetos, lo que significa que es covariante.
Esto no funcionaría con un tipo como IList<T>
, ya que IList<T>
tiene un método Add
. Supongamos que esto le permitiría:
IList<string> strings = new List<string>();
IList<object> objects = strings; // NOTE: Fails at compile time
entonces se podría llamar:
objects.Add(new Image()); // This should work, since IList<object> should let us add **any** object
Esto, por supuesto, un error - por lo IList<T>
puede no estar marcado covariante.
También hay, por cierto, una opción para in
- que es utilizado por cosas como interfaces de comparación.IComparer<in T>
, por ejemplo, funciona de manera opuesta. Puede usar un IComparer<Foo>
concreto directamente como IComparer<Bar>
si Bar
es una subclase de Foo
, porque la interfaz IComparer<in T>
es contravariante.
buen ejemplo sería IObservable y IObserver , definido en el sistema ns en mscorlib. la interfaz pública IObservable , y la interfaz pública IObserver . Del mismo modo, IEnumerator , IEnumerable –
VivekDev