2011-12-30 11 views
8

Sono calpestato da solo con quello che pensavo fosse un codice molto semplice. Il codice parla meglio delle parole, quindi eccolo qui.Interfaccia C# e combinazione generica. Desidera restituire <T> anziché l'interfaccia di 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'. 
} 

Il compilatore non mi permette di fare questo perché IResponse richiede Risultato di essere iResult, però io voglio approfittare dei generici nella classe che implementa e fortemente digitare il risultato di T. Questo è non solo possibile, o mi sono perso qualcosa di banale?

risposta

11

Essi si devono fare IResponse generico troppo:

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; } 
} 

Se si desidera mantenere l'interfaccia IResponse senza il parametro generico in tatto, si può andare anche più elaborato. Il sotto ha le due interfacce, dove la classe in modo trasparente implementa anche l'interfaccia senza il parametro generico:

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; } 
    } 
} 

E, se si vuole stare più vicino alla vostra implementazione originale, è possibile togliere i IResponse<T> e ottenere il seguente :

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 con l'interfaccia rendendo anche generica è che lo uso in un'altra classe dove io non voglio che costringermi a specificare T. – Arkiliknam

+0

Sì ho pensato. Ecco perché ho appena aggiunto la seconda e la terza opzione. –

+0

Ho appena visto il tuo aggiornamento. Sembra buono e ciò che è stato sepolto nella mia testa da qualche parte. Grandi cose! :) – Arkiliknam

1

si dovrebbe fare IResponse generica e cambio tipo di risultato in IResponse come tipo paramter passato a questa interfaccia.

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

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

Se 'solo' vuole "trarre vantaggio dei farmaci generici" non è necessario IResponse.

L'interfaccia sta risolvendo un altro problema, non compatibile con i vostri desideri. Considerate

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

Quindi, o fare IResponse generico troppo o rimuoverlo del tutto.

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

Prova questa

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; } 
    } 
} 
Problemi correlati