2009-09-29 24 views
5

Assumere il seguente codice (Si prega di leggere la mia domanda nei commenti di codice nella classe finale):Come passare una classe generica come parametro per un costruttore della classe non generica

//This is my Generic Class 
public class ClientRequestInfo<K, V> 
{ 
    public string Id { get; set; } 
    private Dictionary<K, V> parameters; 

    public ClientRequestInfo() 
    { 
     parameters = new Dictionary<K, V>(); 
    } 

    public void Add(K key, V value) 
    { 
     parameters.Add(key, value); 
    } 
} 

public class ProcessParameters() 
{ 
    private void CreateRequestAlpha() 
    { 
     ClientRequestInfo<int, string> info = new ClientRequestInfo<int, string>(); 
     info.Add(1, "Hello"); 
     SynchRequest s = new SynchRequest(info); 
     s.Execute(); 
    } 
    private void CreateRequestBeta() 
    { 
     ClientRequestInfo<int, bool> info = new ClientRequestInfo<int, bool>(); 
     info.Add(1, true); 
     SynchRequest s = new SynchRequest(info); 
     s.Execute(); 
    } 
} 

public class SynchRequest 
{ 
    //What type should I put here? 
    //I could declare the class as SynchRequest<K, V> but I don't want 
    //To make this class generic. 
    private ClientRequestInfo<????,?????> info; 
    private SynchRequest(ClientRequestInfo<?????,?????> requestInfo) 
    { 
     //Is this possible? 
     this.info = requestInfo; 
    } 

    public void Execute() 
    {} 
} 
+0

Perché non si desidera utilizzare un SynchRequest generico? – AnthonyWJones

+0

Puoi parlare di cosa faresti in Execute() con il membro info? Questo può fornire una base per una risposta equivalente funzionale. – joshperry

+0

Poiché la classe SynchRequest viene chiamata da altre classi del progetto e lo scopo di SynchRequest è eseguire il servizio e non fornire alcun tipo sulle informazioni del client. Esistono anche classi che utilizzano SynchRequest e non specificano o richiedono alcuna informazione sul client. Quindi non è un buon approccio per rendere questa classe generica. (SynchRequest ha un altro costruttore vuoto) – Ioannis

risposta

7

Se non si desidera rendere generico SynchRequestInfo, è possibile creare una classe base non generica per ClientRequestInfo? -

public abstract class ClientRequestInfo 
{ 
    public abstract void NonGenericMethod(); 
} 

public class ClientRequestInfo<K, V> : ClientRequestInfo 
{ 
    public override void NonGenericMethod() 
    { 
     // generic-specific implementation 
    } 
} 

Poi:

public class SynchRequest 
{ 
    private ClientRequestInfo info; 

    private SynchRequest(ClientRequestInfo requestInfo) 
    { 
     this.info = requestInfo; 
    } 

    public void Execute() 
    { 
     // ADDED: for example 
     info.NonGenericMethod(); 
    } 
} 
+0

Il metodo 'Execute' dovrebbe ovviamente essere dichiarato nella classe base se' CreateRequestAlpha' e 'CreateRequestBeta' devono essere in grado di chiamarlo. –

+0

'Esegui' fa parte di' SynchRequest', non 'ClientRequestInfo'. –

2

La classe deve essere generico se si desiderano variabili membro generiche.

private ClientRequestInfo<????,?????> info; 

È un membro generico.

È possibile utilizzare una classe di base non generico o interfaccia:

class ClientRequestInfo<K,Y> : IClientRequestInfo 

Ma nel tuo esempio, ClientRequestInfo non ha membri non generici, quindi la classe/interfaccia di base sarebbe vuoto e hanno essere castato alla versione generica corretta per essere utile comunque.

1

Hai due opzioni, se si vuole fare non SynchRequestInfo generico.

  1. Creare una classe di base non generica, averla usata entrambe.
  2. Fornire un'interfaccia da utilizzare, come ISynchInfo, e fare in modo che la classe generica implementa l'interfaccia.

In questo caso, preferirei l'approccio dell'interfaccia, poiché potresti voler sincronizzare altri tipi (separati dalle richieste dei clienti) in futuro.

1

Make ClientRequestInfo (K, V) implementa un'interfaccia ClientRequestInfo con le funzioni di interfaccia necessarie a SynchRequest.

Problemi correlati