2013-02-12 16 views
10

considerare questo classe generica:Generici C#: cosa si ottiene facendo una classe wrapper generica?

public class Request<TOperation> 
    where TOperation : IOperation 
{ 
    private TOperation _operation { get; set; } 

    public string Method { get { return _operation.Method; } } 

    public Request(TOperation operation) 
    { 
     _operation = operation; 
    } 
} 

Quali benefici reali fa la versione generica sopra offerta su questa versione non generica di seguito?

public class Request 
{ 
    private IOperation _operation { get; set; } 

    public string Method { get { return _operation.Method; } } 

    public Request(IOperation operation) 
    { 
     _operation = operation; 
    } 
} 

L'interfaccia IOperation è:

public interface IOperation 
{ 
    string Method { get; } 
} 

risposta

13

Con la versione generica di un metodo potrebbe avere un parametro di tipo Request<FooOperation>. Il passaggio in un'istanza di Request<BarOperation> non sarebbe valido.
Quindi, la versione generica consente ai metodi di assicurarsi che ottengano una richiesta per l'operazione corretta.

+0

Gotcha: in altre parole, consente di "chiudere" o specificare il tipo di richiesta in modo più restrittivo dove viene consumato, ma senza la necessità di creare oggetti personalizzati di richiesta per diversi tipi di operazioni. – MalcomTucker

+0

@ MalcomTucker: corretto. –

3

Ad esempio, se si ha

public class SubOperation : IOperation 
{ 
    // implementation ... 
} 

e

public class OtherSubOperation : IOperation 
{ 
    // implementation ... 
} 

Si potrebbe sì che la richiesta non avrebbe mai potuto contenere un elemento di OtherSubOperation, ma entrambi sarebbe IOperations validi.

4

Nel caso avete dato sopra, è difficile dire quale beneficio che si ottiene, sarebbe dipenderà da come questo deve essere utilizzato nella vostra base di codice, ma si consideri il seguente:

public class Foo<T> 
    where T : IComparable 
{ 
    private T _inner { get; set; } 

    public Foo(T original) 
    { 
     _inner = original; 
    } 

    public bool IsGreaterThan<T>(T comp) 
    { 
     return _inner.CompareTo(comp) > 0; 
    } 
} 

contro

public class Foo    
    { 
     private IComparable _inner { get; set; } 

     public Foo(IComparable original) 
     { 
      _inner = original; 
     } 

     public bool IsGreaterThan(IComparable comp) 
     { 
      return _inner.CompareTo(comp) > 0; 
     } 
} 

Se poi ha avuto un Foo<int>, probabilmente non vuole confrontarlo con un Foo<string>, ma non avrebbe modo di bloccaggio che verso il basso utilizzando la versione non generica.

11

In aggiunta a tutte le altre buone risposte, io aggiungo che la versione generica non prende la pena di boxe se vi capita di costruire Request<T> con un T che è un tipo di valore che implementa IOperation. Le caselle di versione non generica ogni volta.

Problemi correlati