2012-01-18 17 views
5

Powiel możliwe:
Reference object instance created using “with” in DelphiJak uzyskać odniesienie do obiektu TQuery utworzonego w instrukcji WITH?

Jedną z metod, które używam do tworzenia obiektów zapytań w Delphi następująco pierwszą próbkę kodu. Daje mi odniesienie do obiektu i mogę następnie przekazać obiekt do funkcji.

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; 

Czy jest to również możliwe w instrukcji WITH, gdzie twój obiekt Create zawarty jest w instrukcji WITH?

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; 

Czy mogę przekazać ten dynamiczny obiekt do funkcji `funcDisplayDataSet (TQuery)?

Chciałbym tylko wiedzieć, czy jest to możliwe. Nie szukam podsumowania , dlaczego instrukcja WITH jest zła lub dobra. W tej rozmowie są inne posty dotyczące przepływu StackOver. *

+1

+1 dla interesującej kwestii, choć podejrzewam, że nie istnieje sposób to zrobić to czysto/wyraźnie, jeśli w ogóle. Jeśli rozwiązaniem okaże się jakiś voodoo, który sprawi, że następny facet będzie musiał pójść i sprawdzić, jak to zrobiłeś, nie powinieneś tego robić. –

+0

To samo pytanie tutaj [referencja-obiekt-wystąpienie-utworzone-używanie-z-w-delphi] (http://stackoverflow.com/questions/791181/reference-object-instance-created-using-with-in-delphi) , z rozwiązaniem dostarczonym przez Aleksandra. –

+4

Po prostu użyj zmiennej lokalnej i weź z.Jeśli pójdziesz zrobić złowrogi hak, tylko po to, by trzymać ZO, to będę musiał cię wytropić i spocząć. –

Odpowiedz

6

To nie jest możliwe, ogólnie rzecz biorąc, w czysty sposób. Twoje opcje:

  1. Dodaj metodę do klasy, która zwraca Self.
  2. Przestań używać with i utwórz lokalną zmienną dla instancji.

Opcja 1 jest wykonalna, jeśli masz kontrolę nad klasą. Ale klasa wygląda raczej dziwnie. Dlaczego klasa potrzebuje metody instancji, która zwróciła instancję? Jeśli nie masz kontroli nad klasą, możesz użyć pomocnika klasowego, jak sugeruje RRUZ, ale traktuję użycie pomocy klasy jako ostateczność. Nigdy nie rozwiązałem problemu z pomocnikiem klasy.

To pozostawia opcję 2. W ten sposób rozwiązałbym problem.

+1

+1 "Nigdy nie rozwiązałem problemu z pomocnikiem klasy" –

+0

Rozwiązałem problem z pomocnikiem klasy ... Przekształciło to 50 godzinną pracę w 6 godzinnej naprawie ... W nagłym przypadku taki był sprawa, są naprawdę przydatne. –

5

A co z używaniem pomocnika klasowego?

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


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

I jak używać tej

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

To działa, ale nie udaje mi się być "czystym". +1 –

+0

David, ja też jestem przeciwny stwierdzeniu 'with', to tylko odpowiedź na pytanie:" Chciałbym tylko wiedzieć, czy to możliwe ". – RRUZ

+0

Prawie tak samo jak rozwiązanie (przez Aleksandra) w powyższym linku. Bez pomocnika klasowego, ale nadal nie "czystego" według miary Davida. –

3

with oświadczenie nie przewiduje odwołanie, które można użyć, aby przejść poza stwierdzeniem.

Z TQuery, można obejść stosując właściwość, która ma odniesienie do dominującej:

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;