2012-01-18 12 views
5

Eventuali duplicati:
Reference object instance created using “with” in DelphiCome si ottiene un riferimento a un oggetto TQuery creato in un'istruzione WITH?

Un metodo che uso per creare oggetti di query in Delphi segue il primo esempio di codice. Mi dà un riferimento all'oggetto e posso quindi passare l'oggetto a una funzione.

procedure SomeProcedure; 
var 
    qry: TQuery; 
begin 
    qry := TQuery.Create(nil); 

    with qry do 
    begin 
    Connection := MyConn; 
    SQL.Text := 'SELECT * FROM PEOPLE'; 
    Open; 

    funcDisplayDataSet(qry); 
    Free; 
    end; 

end; 

E 'anche possibile fare questo in un comunicato in cui il vostro CON oggetto Crea nel contenuta nella dichiarazione CON?

procedure SomeProcedure; 
begin 
    with TQuery.Create(nil) do 
    begin 
    Connection := MyConn; 
    SQL.Text := 'SELECT * FROM PEOPLE'; 
    Open; 

    funcDisplayDataSet(???); // Here I'm unsure how to pass the object created... 
    Free; 
    end; 
end; 

Posso passare questo oggetto dinamico a una funzione come `funcDisplayDataSet (TQuery)?

Vorrei solo sapere se questo è possibile. Non sto cercando un riepilogo sul motivo per cui l'istruzione WITH è buona o cattiva. Ci sono altri post sul flusso StackOver con quella discussione. *

+1

+1 per la domanda interessante, anche se ho il sospetto che non ci sia un modo per fare chiaramente/chiaramente, se non del tutto. Se la soluzione si rivela essere un voodoo che farebbe sì che il prossimo ragazzo debba andare a cercare come hai fatto, allora non dovresti farlo. –

+0

La stessa domanda qui [reference-object-instance-created-using-with-in-delphi] (http://stackoverflow.com/questions/791181/reference-object-instance-created-using-with-in-delphi) , con una soluzione fornita da Alexander. –

+4

Basta usare una variabile locale e togliere il WITH.Se vai a fare qualche trucco malvagio, solo per tenere la CON dentro, poi dovrò rintracciarti e metterti nei pantaloni. –

risposta

6

Questo non è possibile, in generale, in modo pulito. Opzioni disponibili:

  1. Aggiungere un metodo alla classe che restituisce Self.
  2. Interrompere l'utilizzo di with e creare una variabile locale per l'istanza.

L'opzione 1 è valida se si ha il controllo sulla classe. Ma lascia la classe molto strana. Perché una classe dovrebbe aver bisogno di un metodo di istanza che ha restituito l'istanza? Se non hai il controllo sulla classe, potresti usare un helper di classe come suggerisce RRUZ, ma considero l'utilizzo degli helper di classe come ultima risorsa. Non ho mai risolto un problema con un aiutante di classe.

Ciò lascia l'opzione 2. Questo sarebbe come risolverei il problema.

+1

+1 "Non ho mai risolto un problema con un helper di classe" –

+0

Ho risolto un problema con un helper di classe ... Ha trasformato un lavoro di 50 ore in una correzione di 6 ore ... In un'emergenza, tale era il caso, sono davvero a portata di mano. –

5

Che ne pensi di un helper di classe?

type 
    TQueryHelper = class helper for TQuery 
    public 
    function Instance: TQuery; 
    end; 


function TQueryHelper.Instance: TQuery; 
begin 
    Result := Self; 
end; 

E utilizzare come questo

With TQuery.Create(nil) do 
    begin 
    SQL.Text:='Select * from OTGH'; 
    ShowMessage(Instance.SQL.Text); 
    end; 
+3

Beh, questo fa il lavoro ma fallisce il mio test di essere "pulito". +1 –

+0

David, anch'io sono contro la frase 'with', questa è solo una risposta al comeom '... vorrei solo sapere se questo è possibile'. – RRUZ

+0

Quasi uguale alla soluzione (di Alexander) nel mio link sopra. Senza aiuto di classe, ma non ancora "pulito" dalla misura di David. –

3

Il with comunicato non fornisce un riferimento che è possibile utilizzare per passare al di fuori della dichiarazione.

Con un TQuery, si potrebbe ottenere intorno ad esso utilizzando una proprietà che ha un riferimento al padre:

begin 
    with TQuery.Create(nil) do 
    begin 
    Connection := MyConn; 
    SQL.Text := 'SELECT * FROM PEOPLE'; 
    Open; 
    // Fields have reference to parent component, but your implementation may vary 
    funcDisplayDataSet(TQuery(Fields.Fields[0].GetParentComponent)); 
    Free; 
    end; 
end;