2012-03-19 6 views
5

Tengo las siguientes declaraciones de interfaz:¿Cómo paso dos objetos concretos similares a un método con parámetros de interfaz que implementan genéricos en C#?

interface IOrder<T> where T: IOrderItem 
{ 
    IList<T> Items { get; set; } 
} 

interface IDistro<T> : IOrder<T> where T: IOrderItem 
{ 

} 

Tengo dos clases concretas, así:

// DistroItem implements IOrderItem 
public class Distro : IDistro<DistroItem> 
{ 
    public IList<DistroItem> Items { get; set; } 
} 

// PerishableOrderItem implements IOrderItem 
public class PerishableOrder : IDistro<PerishableOrderItem> 
{  
    public IList<PerishableOrderItem> Items { get; set; } 
} 

Por último, tengo un método de servicio estática para guardar en la base de datos:

public static void UpdateDistro(IDistro<IOrderItem> distro) 
{ 

} 

Mi problema es, ¿cómo paso una distribución de cualquier tipo de concreto a mi método estático? Lo siguiente no se compila:

Distro d = new Distro(); 
UpdateDistro(d); 

El error es:

The best overloaded method match for UpdateDistro(IDistro<IOrderItem>)' has some invalid arguments

Es contravarianza la respuesta? Traté de agregar <in T> a la declaración de la interfaz original, pero eso agregó más errores que no pude resolver. Esta es mi primera incursión en profundidad en las interfaces y estoy seguro de que los genéricos están agregando complejidad, por lo que podría haber una falta fundamental de comprensión aquí.

Respuesta

6

Has probado esto:

public static void UpdateDistro<T>(IDistro<T> distro) 
    where T : IOrderItem 
{ 
} 

EDIT:

Con implementaciones vacías para DistroItemPerishableItem y clases (tanto la implementación de IOrderItem), Tengo la siguiente compilación sin errores:

Distro d = new Distro(); 
PerishableOrder p = new PerishableOrder(); 

UpdateDistro(d); 
UpdateDistro(p); 
+0

Sí, lo intenté. Todavía se quejaba cuando pasaba el objeto 'Distro'. 'UpdateDistro (myDistro)' lanzó el mismo error. – IronicMuffin

+0

Veo que esto se está levantando. Lo marcaré como la respuesta si puede mostrarme la forma correcta de llamar al método. – IronicMuffin

+0

Gracias. Perdon por ser un dolor. Tenía restos de otras pruebas en las que estaba recurriendo a los tipos de interfaz, etc. Esto funciona como se desea. ¡Muy apreciado! – IronicMuffin

0

Puede definir un parámetro genérico covariante en su interfaz, necesita cambiar la interfaz un poco aunque para asegurarse de que no es T utiliza contravariantly:

public interface IOrder<out T> where T : IOrderItem 
{ 
    IEnumerator<T> Items { get; } 
} 

public interface IDistro<out T> : IOrder<T> where T : IOrderItem 
{ 

} 

Para definir T como parámetro coverient (out), permite la conversión implícita de clases que implementan las interfaces de variantes.

Cuestiones relacionadas