Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi (D2009) Generics mit Array als Feldvariable: Interner Fehler (https://www.delphipraxis.net/150107-d2009-generics-mit-array-als-feldvariable-interner-fehler.html)

stimpinski 7. Apr 2010 15:10


(D2009) Generics mit Array als Feldvariable: Interner Fehler
 
Moin!

Bei der Verwendung von Generics unter Delphi 2009 bin ich kürzlich über folgende Fehlermeldung gestolpert:
Zitat:

[DCC Fataler Fehler] F2084 Interner Fehler: L2084
Daraufhin habe ich das Problem isoliert und mit möglichst minimalem Quellcode reproduziert. Das Projekt beinhaltet zwei Units:

Delphi-Quellcode:
unit testGenerics;

interface

uses
  Controls;

type

  TMyGenericClass<T> = class
  private
    FIntegerArray: Array of Integer; // Array als Feldvariable einer generischen Klasse
  public
    constructor Create;
  end;

implementation

{ TMyGenericClass<T> }

constructor TMyGenericClass<T>.Create;
begin
  // do nothing
end;

end.
Delphi-Quellcode:
unit main;

interface

uses
  testGenerics,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type

  TMyDummieClass = class
    constructor Create;
  end;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FMyGenericClass: TMyGenericClass<TMyDummieClass>;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyDummieClass }

constructor TMyDummieClass.Create;
begin
  // do nothing
end;

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  FMyGenericClass := TMyGenericClass<TMyDummieClass>.Create; // verursacht die Fehlermeldung
end;

end.
Kann es sein dass Delphi ein Problem mit generischen Klassen hat, die Arrays als Feldvariablen haben? Wenn ich die Feldvariable entferne compiliert und läuft es fehlerfrei, ebenso wenn ich die generische Klasse zu einer nicht generischen mache. Hat jemand bereits Erfahrungen mit diesem Problem gesammelt? Compiliert das ganze unter Delphi 2010? Ein funktionierender Workaround ist folgende Variante:

Delphi-Quellcode:
type

  TIntegerArray = Array of Integer;

  TMyGenericClass<T> = class
  private
    FIntegerArray: TIntegerArray;
  public
    constructor Create;
  end;
In besonderen Fällen kann man auch einen Wrapper um den Array basteln, andererseits wäre das ziemlich umständlich.

himitsu 7. Apr 2010 17:15

Re: (D2009) Generics mit Array als Feldvariable: Interner Fe
 
Ja, die erste Generation der Generics hat einige Progleme.
(wir hoffen daß Vieles in D2010 besser läuft)

Stevie 8. Apr 2010 10:21

Re: (D2009) Generics mit Array als Feldvariable: Interner Fe
 
Zitat:

Zitat von himitsu
(wir hoffen daß Vieles in D2011 besser läuft)

fixed :roll: :lol:

stimpinski 15. Apr 2010 16:29

Re: (D2009) Generics mit Array als Feldvariable: Interner Fe
 
So, nach einigem experimentieren mit den Delphi2009 Generics bin ich zu folgendem Ergebnis gekommen:

1. Wenn du Arrays als Feldvariablen einer generischen Klasse verwenden möchtest, definiere sie vorher als eigenen Typen.

Delphi-Quellcode:
type

  TMyIntegerArray = Array of Integer;

  TMyGenericClass<T> = class(TObject)
  private
    FIntegerArray: TMyIntegerArray;
  public
    constructor Create;
    // etc
  end;
2. Wenn du eine generische Klasse von einer generischen Klasse verwenden möchtest, dann baue einen Wrapper um die innere generische Klasse.

Delphi-Quellcode:
type

  TMyDummieClass = class(TObject)
    constructor Create;
    // etc
  end;

  TMyGenericClass<T> = class(TOjbect)
    constructor Create;
    // etc
  end;

  // wrapper klasse für TMyGenericClass<TMyDummieClass>
  TMyGenericClassWrapper = class(TObject)
  private
    FMyGenericClass: TMyGenericClass<TMyDummieClass>;
  public
    constructor Create; // ruft auf FMyGenericClass := TMyGenericClass<TMyDummieClass>.Create;
    // etc
  end;

  TMyOtherGenericClass<T> = class(TObject)
    constructor Create;
    // etc
  end;
Statt
Delphi-Quellcode:
var
  LLocalVariable: TMyOtherGenericClass<TMyGenericClass<TMyDummieClass>>;
verwendet man einfach
Delphi-Quellcode:
var
  LLocalVariable: TMyOtherGenericClass<TMyGenericClassWrapper>;
Das ist zwar wenig elegant, weil ich für jeden Typ den ich in die innere generische Klasse stecke einen neuen Wrapper schreiben muss, andererseits erhalte ich jetzt keine kryptischen Fehlermeldungen vom Compiler mehr.

himitsu 15. Apr 2010 16:41

Re: (D2009) Generics mit Array als Feldvariable: Interner Fe
 
Wenn du diese Typen dennoch nicht öffentlich rumliegenlassen willst:
Delphi-Quellcode:
type

  TMyGenericClass<T> = class(TObject)
  private
    type TMyIntegerArray = Array of Integer;
  private
    FIntegerArray: TMyIntegerArray;
  public
    constructor Create;
    // etc
  end;

  TMyGenericClass<T> = class(TObject)
  private
    type TMyIntegerArray = Array of Integer;
    var FIntegerArray: TMyIntegerArray;
  public
    constructor Create;
    // etc
  end;
PS: Unit Types > TIntegerDynArray


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:57 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz