2009-04-29 24 views
15

C# 4.0 va a admitir la covarianza y la contravarianza. Pero no entiendo claramente los beneficios de esta nueva característica. ¿Puedes explicarme (claramente) por qué lo necesitamos?¿Cuáles son los beneficios de la covarianza y la contravarianza?

+0

[Covarianza vs contravariancia] (http://izlooite.blogspot.com/2011/04/covariance-and-contravariance.html) –

+0

Bart De Smet tiene una gran entrada de blog sobre covarianza y contravarianza [aquí] (http: //bartdesmet.net/blogs/bart/archive/2009/04/13/c-4-0-feature-focus-part-4-generic-co-and-contra-variance-for-delegate-and-interface- types.aspx). –

Respuesta

7

Simplemente le permiten hacer algunas cosas que son conceptualmente válidas y formalmente aceptables, pero que actualmente no se permiten debido a restricciones de idioma. Por ejemplo:

IEnumerable<int> ints = new List<int> { 1, 2, 3 }; 

Action<IEnumerable<object>> PrintThings = 
    x => { foreach(var thing in x) Console.WriteLine(thing); }; 

PrintThings(ints); // doesn't compile right now :( will compile in 4.0 

No existe una razón fundamental por la que esto no funcione o no funcione; simplemente no está permitido en el idioma. Al permitirlo, usted facilita la vida de los programadores cuando tal operación sería natural para ellos.

+0

La razón fundamental por la cual lo anterior no funcionará antes de 4.0 es que no hay forma en la sintaxis de permitirlo sin perder seguridad de tipo. Si lo permite para su ejemplo, necesariamente también le permitirá ejemplos donde no se preserva la seguridad del tipo. – Eddie

+0

Correcto, y es por eso que están agregando las nuevas palabras clave "in" y "out" para admitirlo (y IEnumerable será para permitir este escenario.) – mquander

1

Hay un buen escrito que habla sobre este tema here.

5

Hay muchos conceptos erróneos sobre cómo y qué funcionará en 4.0. La mejor explicación que he leído hasta ahora fue escrita por Marc Gravell. Ver su blog aquí:

http://marcgravell.blogspot.com/2009/02/what-c-40-covariance-doesn-do.html

Sólo para reiterar, una gran cantidad de gente en que esto va a funcionar en 4.0:

public class Base{} 
public class Derived : Base {} 

..en alguna otra clase

List<Derived> derived.... 

public void Method(List<Base> b){} 

Incluso en 4.0, no podrá pasar la Lista a este método. Como Marc señala, eso es lo que las limitaciones genéricas están ahí para, y se puede hacer desde el 2,0

+0

Esto me parece un extraño no sequitur. La única razón por la que no puede pasar la Lista es porque las Listas son mutables; por supuesto, no puede pasar de esa manera, ya que agregarle elementos rompería las restricciones de tipo en él. – mquander

+0

@mquander: ¿Un extraño no sequitur? La API (pre 4.0) no tiene nada que decir, "puedes hacer esta operación solo si el objeto es inmutable". – Eddie

+0

Mi punto es simplemente que el hecho de que la Lista le permite agregar y cambiar Ts es por qué no tiene sentido. Si intentó agregar el parámetro "out" en IList para permitir esto, esos métodos ya no funcionarían según lo previsto. – mquander

2

Uno de los beneficios que, en mi opinión, covarianza va a ayudar mucho es con Genéricos.

Encontré varias situaciones donde uno necesita explícitamente usar Cast a convertir un tipo específico a su base.

class Foo { } 
class Bar : Foo { } 

// ... 

IEnumerable<Foo> foos = new List<Foo>(); 
IEnumerable<Bar> bars = new List<Bar>(); 

foos = bars.Cast<Foo>(); 

// C# 4.0 
foos = bars; 

Aquí hay una good reference sobre el tema.

+0

Aún así, el uso excesivo de cursivas fue un buen toque. – bzlm

+0

Lo siento :(se olvidó de la clase def –

Cuestiones relacionadas