2012-07-25 14 views
6

Estoy implementando una interfaz para inyectar lógica empresarial personalizada en un marco que utiliza Microsoft Unity. Mi problema principal es que una interfaz que necesito para implementar define el siguiente método:Implementación de la interfaz con el tipo genérico que está menos restringido que el de un método que necesito llamar

T InterfaceMethod<T>(); 

T no tiene limitaciones. En mi código, tengo que llamar a un método de una biblioteca de 3 ª parte diferente, con una firma de método de

T AnotherMethod<T>() where T: class; 

El tipo T es significativo a la lógica de AnotherMethod. ¿Hay alguna manera de llamar al AnotherMethod<T>() dentro de mi implementación, sin usar el reflejo? Obviamente necesito tomar medidas alternativas si T es un tipo de valor. ¿Hay quizás una forma de autobox para solucionar esto?

+0

¿Qué AnotherMethod () lo hacen con T? Si quieres encasillarlo, simplemente prepáralo para un objeto de antemano ... –

+0

No estoy seguro de que me ayude, ya que estoy obteniendo un error de compilación con respecto a que T necesita ser un tipo de referencia. – techphoria414

Respuesta

1

No creo que lo que estás buscando sea posible sin reflexión. En el mejor de los casos, puede llamar al AnotherMethod<object>() y emitir el resultado. Pero esto solo funcionaría realmente bien si AnotherMethod 's T no es importante para sus propósitos.

+0

Parece que en mi caso estás en lo correcto. – techphoria414

2

No estoy seguro de que esto sea exactamente lo que necesita, pero esto le permite llamar a AnotherMethod desde InterfaceMethod sin usar la reflexión. Todavía usa un Convert.ChangeType embargo.

La idea es hacer que la implementación de la clase sea genérica con una restricción (aquí Tin). Luego, convierte el tipo sin restricciones T de InterfaceMethod a Tin. Finalmente puede llamar a AnotherMethod con el tipo restringido. Lo siguiente funciona bien con cadenas.

public interface ITest 
{ 
    T InterfaceMethod<T> (T arg); 
} 

public interface ITest2 
{ 
    U AnotherMethod<U>(U arg) where U : class; 
} 

public class Test<Tin> : ITest, ITest2 where Tin : class 
{ 
    public T InterfaceMethod<T> (T arg) 
    { 
     Tin argU = arg as Tin; 
     if (argU != null) 
     { 
      Tin resultU = AnotherMethod(argU); 
      T resultT = (T)Convert.ChangeType(resultU,typeof(T)); 
      return resultT; 
     } 
     return default(T); 
    } 

    public U AnotherMethod<U> (U arg) where U : class { return arg; } 
} 
+0

+1 por ingenio pero desafortunadamente con la forma en que mi clase necesita ser instanciada por Unity en el código de framework, no puedo utilizar genéricos en la clase en sí. Edité mi pregunta para aclarar la situación un poco. Definitivamente podría funcionar para alguien donde tengan la capacidad de especificar al crear una instancia de la clase. – techphoria414

0

Lo que los otros están diciendo es que se puede pasar por objeto como éste:

public interface ITest 
{ 
    T InterfaceMethod<T>(T arg); 
} 

public interface IAnotherTest 
{ 
    U AnotherMethod<U>(U arg) where U : class; 
} 

public class Test : ITest 
{ 
    private IAnotherTest _ianothertest; 

    public T InterfaceMethod<T>(T arg) 
    { 
     object argU = arg as object; 
     if (argU != null) 
     { 
      object resultU = _ianothertest.AnotherMethod(argU); 
      T resultT = (T)Convert.ChangeType(resultU, typeof(T)); 
      return resultT; 
     } 
     return default(T); 
    } 
} 
+0

Como señala Tim S, esto solo funciona si el tipo de T no es significativo para el método llamado. Desafortunadamente es. – techphoria414

Cuestiones relacionadas