Einzelnen Beitrag anzeigen

Panthrax

Registriert seit: 18. Feb 2005
286 Beiträge
 
Delphi 2010 Enterprise
 
#8

Re: Typumwandlung mit Generika

  Alt 30. Mär 2009, 00:28
Sebastian hat es eigentlich schon gesagt. Trotz rotem Kasten:

Das StringList-Beispiel ist aus der Welt ohne Generika. Dort kann man eine Variable nicht in einen Typ umwandeln, der außerhalb der Vorfahrlinie steht ("StringList as TComponent"). In der Welt mit Generika scheint (schien!) aber genau das zu funktionieren. Nachdem es sich bei mir etwas gesetzt hat, ist bei mir, glaube ich, der Groschen gefallen. Der folgende Quelltext soll nur noch einmal meine Überlegung verdeutlichen (Win32 ohne Generika, siehe TClassA1 und TClassA2):
Delphi-Quellcode:
program Project1;

{$AppType Console}

uses
  SysUtils;

type
  TGenericClassA = class
    public
    procedure Method1; virtual;
  end;
  TGenericClassB = class(TGenericClassA)
    public
    procedure Method1; override;
  end;
  { TClassA = TGenericClassA<TObject>; ist etwa }
  TClassA1 = TGenericClassA;
  { und nicht }
  TClassA2 = class(TGenericClassA);

  TClassB = TGenericClassB;

{ TGenericClassA }

procedure TGenericClassA.Method1;
begin
  WriteLn('A: TGenericClassA.Method1 aufgerufen');
end;

{ TGenericClassB }

procedure TGenericClassB.Method1;
begin
  WriteLn('B: TGenericClassB.Method1 aufgerufen');
end;

procedure Test;
var
  B: TClassB;
begin
  B:=TClassB.Create;
  try
    { 1 }
    TClassA1(B).Method1;
    (B as TClassA1).Method1;

    { 2 }
    TClassA2(B).Method1;
    (B as TClassA2).Method1;
    { [Pascal Fehler] Project1.dpr(50): E2010 Inkompatible
    Typen: 'TClassA2' und 'TGenericClassB' }

  finally
    B.Free;
  end;
end;

begin
  Test;
  ReadLn;
end.
Ich hatte mir die Vorfahrlinien irgendwie so gedacht:
TGenericClassA<T> >> TGenericClassB<T>
TGenericClassA<TObject> >> TGenericClassB<TObject> >> TClassB
TGenericClassA<TObject> >> TClassA

TClassA wäre also nicht in der Linie von TClassB.

Tatsächlich sind die Linien so:
TGenericClassA<T> >> TGenericClassB<T>
TGenericClassA<TObject> >> TGenericClassB<TObject> = TClassB {2}
TGenericClassA<TObject> = TClassA {2}

Aus 1 und 2 ließe sich also formulieren:
TClassA >> TGenericClassB<TObject> = TClassB

Damit liegt TClassA in der Vorfahrlinie und die Typumwandlung "B as TClassA" ist keine Überraschung mehr. -- Vielen Dank!

Ich glaub' ich muss mir unbedingt ne Möglichkeit verschaffen mit Generika selbst ein bisschen herumzuspielen...

@I.A: Ja, allerdings, ich habe keine Möglichkeit, Generika einmal testweise auszuprobieren. Deshalb habe ich jemanden gefragt. Himitsu war so freundlich.
"Es gibt keine schlimmere Lüge als die Wahrheit, die von denen, die sie hören, missverstanden wird."
  Mit Zitat antworten Zitat