Generyki, klasa w zmiennej

Odpowiedz Nowy wątek
2014-05-19 19:33
0

Cześć, mam taki problem. Mam metodę generyczną i funkcję, która na podstawie pewnych danych zwraca mi TClass:


var
   cType: TClass;
begin
  cType:=GetClassType(parameters);
end;

I teraz pytanie jest takie. Czy mogę w jakiś sposób dynamicznie wskazać typ generyczny w funkcji? Coś w sensie:

  Foo<cType>();  

Czy jest w ogóle jakikolwiek taki mechanizm?

Pozostało 580 znaków

2014-05-20 10:26
0

O ile dobrze cię zrozumiałem, do nie da się dynamicznie typować parametrów metod. Delphi to strong typing, ale zawsze może w owej metodzie sprawdzić co trzeba i rzucić odpowiednim wyjątkiem.

Jest mechanizm ograniczeń w typach generycznych (podobny do tego z C#) więcej o Constraints in Generics
A używa się tego tak:


interface
type
  TMyClass = class
  public
    function Foo<T: class>(const AClass: T): T;
  end;

implementation

function TMyClass.Foo<T>(const AClass: T): T;
begin
  // coś tam ze zmienną AClass, która jest typu T z ograniczeniem do klasy
end;

Ograniczenie możesz zawęzić do konkretnego typu klasowego (ale nie tylko klasy, szczegóły w manualu) czyli deklaracja metody Foo może wyglądać tak:

type
  TMyClass = class
  public
    function Foo<T: TComponent>(const AClass: T): T;
  end;

A używa się tego normalnie jak metody, czyli:

  // to wykona się poprawnie
  Foo(TComponent(ASomeObject)); 

  // a tu dostaniesz błąd na etapie okmpilacji
  Foo('string!'); 

Pozostało 580 znaków

2014-05-20 19:10
0

Chcę zrobić coś w stylu fabryki obiektów. Ale nie chcę dla każdego obiektu tworzyć oddzielnej metody. Chyba jednak posłużę się RTTI.

Pozostało 580 znaków

2014-05-21 13:01
1

Można za pomocą RTTI, ale nie trzeba.
Jakiego rodzaju są to obiekty?
Od dawna używam fabryki dla formularzy w Delphi, durnowata (dummy) implementacja takiej fabryki była dołączona do mojego wykładu ze zlotu programistów Delphi o AnyDAC (2008 rok? czy jakoś tak ;-))
Generalnie sprowadza się to do kilku elementów:

  1. Klasa musi dziedziczyć z TPersistent
  2. Klasa musi być zarejestrowana za pomocą RegisterClass(TypKlasowy)

A używa się tego tak:

// rejestracja klasy 
RegisterClass(TMyClass);

// pobieranie klasy i kreowanie obiektu
var
  lClass : TPerstistentClass;
  lObject : TPersistent;
begin
  lClass := GetClass('TMyClass');
  if lClass <> nil then
    lObject := lClass.Create;
end;

I w sumie to wszystko.

Pozostało 580 znaków

2014-05-22 10:12
0

Tak wiem, wszystko rozbija się o to, że to nie są klasy TPersistent. Wywodzą się bezpośrednio z TObject. Myślałem nad utworzeniem własnego mechanizmu rejestracji analogicznego do RegisterClass, ale z RTTI było szybciej, bo to tylko kilka linijek kodu.

Pozostało 580 znaków

2014-05-22 10:42
0

W Delphi dla fabryki nie trzeba żadnych generyków:

function Make(AType:TClass):TObject;
begin
  Result:=AType.Create();
end;

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2014-05-22 11:04
0

Tak, ale to właśnie nie jest żadna fabryka - ten kod wymaga typu klasowego, wpisanego literalnie z kodu do którego masz dostęp.
RTTI pozwoli tworzyć dowolny typ obiektu, znając jego nazwę lub cokolwiek, co pozwoli go jednoznacznie zidentyfikować (oczywiście potrzebny będzie jakiś mechanizm rejestracji klasy, może być własny, mogą to być cale metadane opisujące klasę i sposób jej kreacji).
Poza tym, jak ten kod poradzi sobie z konstruktorem z parametrami? Nie poradzi sobie.
Osobiście zrozumiałem, że Juhasowi zależy na mechanizmie podobnym do refleksji - ale tego nie wiem.

Pozostało 580 znaków

2014-05-22 12:36
0

Nie, nie musi być literalnie.
Może być ze zmiennej:

var T:TClass;
T:=TStringList;
Make(T);

Albo wręcz z innego obiektu:

bmp2:=Make(bmp.ClassType);

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2014-05-22 13:07
0

Maaatko... niech będzie, a więc tak: "[...] ten kod wymaga typu klasowego, wpisanego literalnie z kodu lub przekazanego przez zmienną, do którego masz dostęp (typu klasy) w miejscu użycia."
Teraz lepiej? A co to ma wspólnego z refleksją i fabryką? Nic.

PS. Na tym forum zawsze takie przedszkolne rozmowy odchodzą?

PS: I tak, i nie - nie każdy jest geniuszem Twojego pokroju, i nie każdy rozumie wszystko tak dobrze jak Ty; Sam wołałeś ostatnio moderatorów (http://4programmers.net/Forum/Delphi_Pascal/162467-tworzenie_koszyka_bazy_danych?p=1035257#id1035257), zgłaszając, że wątek zawiera sporo postów nie na temat, a teraz sam takie publikujesz; Więc jeśli masz coś sensownego do powiedzenia to pisz, a jeśli nie - zostaw deskusję w spokoju; Po co wystawiać na próbę swoje i cudze nerwy; - furious programming 2014-05-22 16:18

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0