OK, vamos a reemplazar con A
Fish
, IA
con IAnimal
, B
con Aquarium
, y IB<T>
con IContainer<T>
. Y lo añadiremos un miembro de IContainer<T>
, y una segunda aplicación de IAnimal
:
// Model
public class Fish : IAnimal { }
public class Tiger : IAnimal { }
// ModelLogic
public class Aquarium : IContainer<Fish>
{
public Fish Contents { get; set; }
}
// Model Interface
public interface IAnimal { }
// ModelLogic Interface
public interface IContainer<T> where T : IAnimal
{
T Contents { get; set; }
}
IContainer<IAnimal> foo = new Aquarium(); // Why is this illegal?
foo.Contents = new Tiger(); // Because this is legal!
se puede poner un tigre en foo - foo se escribe como un contenedor que puede contener cualquier animal. Pero solo puedes poner un pez en un acuario. Dado que las operaciones que puede realizar legalmente en un Aquarium
son diferentes que las operaciones que puede realizar en un IContainer<IAnimal>
, los tipos no son compatibles.
la función que desea se llama genérica covarianza interfaz y es apoyado por C# 4, pero hay que demostrar al compilador que nunca se va a poner un tigre en su tanque de peces. Lo que se quiere hacer es:
// Model
public class A : IA { }
// ModelLogic
public class B : IB<A> { }
// Model Interface
public interface IA { }
// ModelLogic Interface
public interface IB<out T> where T : IA { }
Aviso la anotación de covarianza en IB
. Esto out
significa que T
solo se puede usar como salida, no como entrada. Si T
es solo una salida, entonces no hay forma de que alguien coloque un tigre en esa pecera porque no hay una propiedad o método de "ponerlo en" posible.
Escribí una serie de artículos de blog mientras agregamos esa característica a C#; si usted está interesado en las consideraciones de diseño que entraron en la función, consulte:
http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/
¿Qué versión de C# estás usando? – Oded
[Preguntas frecuentes sobre covarianza y contradicción] (http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx) y [esta serie de blogs] (http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/) por Eric Lippert – Oded
B es un IB , no un IB. –
Servy