2011-12-30 13 views
8

Han pisado mis propios dedos del pie con lo que pensé que era una pieza muy simple de código. El código habla mejor que las palabras, así que aquí está.Interfaz C# y combinación genérica. ¿Desea devolver <T> en lugar de su interfaz base

public interface IResponse 
{ 
    IResult Result { get; set; } 
} 

public class Response<T> : IResponse 
    where T : IResult 
{ 
    public T Result { get; set; } 
    // COMPILER ERROR: Property 'Result' cannot be implemented property from interface 'IResponse'. Type should be 'IResult'. 
} 

El compilador no me permite hacer esto porque requiere IResponse resultado ser iResult, sin embargo quiero tomar ventaja de los genéricos en la clase que implementa y escriba el resultado fuertemente a T. Es esto simplemente no es posible, o me he perdido algo trivial?

Respuesta

11

Ellos tienen que hacer IResponse genérica también:

public interface IResponse<T> 
    where T : IResult 
{ 
    T Result { get; set; } 
} 

public class Response<T> : IResponse<T> 
    where T : IResult 
{ 
    public T Result { get; set; } 
} 

Si desea mantener la interfaz IResponse sin el parámetro genérico en el tacto, puede ir aún más elegante. La continuación tiene las dos interfaces, donde la clase de forma transparente también implementa la interfaz sin el parámetro genérico:

public interface IResponse 
{ 
    IResult Result { get; set; } 
} 

public interface IResponse<T> : IResponse 
    where T : IResult 
{ 
    T Result { get; set; } 
} 

public class Response<T> : IResponse<T> 
    where T : IResult 
{ 
    public T Result { get; set; } 

    IResult IResponse.Result 
    { 
     get { return Result; } 
     set { Result = (T)value; } 
    } 
} 

Y, si desea permanecer más cerca de su aplicación original, puede despojar a cabo la IResponse<T> y obtener la siguiente :

public interface IResponse 
{ 
    IResult Result { get; set; } 
} 

public class Response<T> : IResponse 
    where T : IResult 
{ 
    public T Result { get; set; } 

    IResult IResponse.Result 
    { 
     get { return Result; } 
     set { Result = (T)value; } 
    } 
} 
+0

problema de hacer la interfaz genérica también es que lo uso en otra clase en la que no quiero que me obligan a especificar T. – Arkiliknam

+0

Sí he pensado en eso. Es por eso que acabo de agregar la segunda y la tercera opción. –

+0

Acabo de ver su actualización. Se ve bien y lo que estaba enterrado en mi cabeza en alguna parte. ¡Buena cosa! :) – Arkiliknam

1

usted debe hacer IResponse tipo genérico y el cambio del resultado en IResponse tipo parametro pasado a esta interfaz.

public interface IResponse<T> where T : IResult 
{ 
    T Result { get; set; } 
} 

public class Response<T> : IResponse<T> 
{ 
    public T Result { get; set; } 
} 
4

Si 'sólo' quiere "tomar ventaja de los genéricos" no es necesario IResponse.

La interfaz resuelve otro problema, uno que no es compatible con su deseo. Consideremos

IResponse r = x ? new Response<int>() : new Response<string>(); 
r.Result = ... // what type? 

Así que, o hacen demasiado genérica IResponse o eliminarlo por completo.

1
public interface IResponse<T> where T : IResult 
{ 
    T Result { get; set; } 
} 

public class Response<T> : IResponse<T> where T : IResult 
{ 
    public T Result { get; set; } 
    // NO MORE COMPILER ERROR 
} 
2

probar este

public class Response<T> : IResponse 
    where T : IResult 
{ 
    public T Result { get; set; } 
    // COMPILER ERROR: Property 'Result' cannot be implemented property from interface 'IResponse'. Type should be 'IResult'. 

    IResult IResponse.Result 
    { 
     get { return this.Result; } 
     set { this.Result = (T)value; } 
    } 
} 
Cuestiones relacionadas