Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Generics.TObjectList<T> mit Compilerfehler URW1111 (https://www.delphipraxis.net/172831-generics-tobjectlist-t-mit-compilerfehler-urw1111.html)

HJay 24. Jan 2013 16:42


Generics.TObjectList<T> mit Compilerfehler URW1111
 
Ich möchte übungshalber eigene Sortierroutinen schreiben, um eine Generics.TObjectList<> zu sortieren und um das Generics-Konzept zu verstehen.

In meinem Beispielprojekt erhalte ich aber immer dem ominösen Compiler Fehler "Interner Fehler URW1111". Was mache ich falsch und was bedeutet das überhaupt?

Könnt Ihr den Fehler bei Euch reproduzieren? Ich habe alles soweit möglich vereinfacht und schließlich folgenden Code als eigenständiges Testprojekt extrahiert. Neues Projekt anlegen, eine Memo-Box und ein Button drauf ziehen.

Code:
unit MainForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,

  SortObjectListUnit;

type
  TForm1 = class(TForm)
    Memo1: TMemo; { TMemo1 enthält sechs Zeilen mit je einem Wort }
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    function CompareTest(AItem, BItem: TMyItem): Integer;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
  var A : TTestList;
      j : Integer;

  function MakeTestItem(AString: String): TMyItem;
  begin Result := TMyItem.Create; Result.Dummy := AString; end;
// auf diese Leerzeile zeigt "F2084 Interner Fehler: URW1111"
begin
  A := TTestList.Create(True);
  for j := 0 to Pred(Memo1.Lines.Count) do A.Add(MakeTestItem(Memo1.Lines[j]));

  A.QuickSort(0, Pred(A.Count), CompareTest);

  Memo1.Clear;
  for j := 0 to Pred(A.Count) do Memo1.Lines.Add(A[j].Dummy);

  A.Free;
end;

function TForm1.CompareTest(AItem, BItem: TMyItem): Integer;
begin
  Result := CompareStr(AItem.Dummy, BItem.Dummy);
end;

end.
Code:
unit SortObjectListUnit;

interface

uses
  Windows, Messages, SysUtils, Generics.Collections;

type
  TSortObjectList<T: class> = class(TObjectList<T>)
    type TCompareItems<T> = function(AItem, BItem: T): Integer of Object;
    procedure QuickSort(Left, Right: Integer; ACompareMethod: TCompareItems<T>); overload;
  end;

  TMyItem = class(TObject)
    Dummy: String;
  end;

  TTestList = class(TSortObjectList<TMyItem>)
  end;

implementation

procedure TSortObjectList<T>.QuickSort(Left, Right: Integer; ACompareMethod: TCompareItems<T>);
  var I, J: Integer;
      Pivot, Temp: T;
begin { QuickSort procedure from Classes.pas. }
  repeat
    I := Left;
    J := Right;
    Pivot := Items[(Left + Right) shr 1];
    repeat
      while ACompareMethod(Items[I], Pivot) < 0 do Inc(I);
      while ACompareMethod(Items[J], Pivot) > 0 do Dec(J);
      if I <= J then begin
        Temp := Items[I];
        Items[I] := Items[J];
        Items[J] := Temp;
        Inc(I);
        Dec(J);
      end;
    until I > J;
    if Left < J then QuickSort(Left, J, ACompareMethod);
    Left := I;
  until I >= Right;
end;

end.

daywalker9 24. Jan 2013 17:18

AW: Generics.TObjectList<T> mit Compilerfehler URW1111
 
Versuch es mal so, so sollte es klappen.

Delphi-Quellcode:
type
  TCompareItems<T> = function(AItem, BItem: T): Integer of Object;

  TSortObjectList<T: class> = class(TObjectList<T>)

    procedure QuickSort(Left, Right: Integer; ACompareMethod: TCompareItems<T>); overload;
  end;
Wenn Du es in der Typen Deklaration von TSortObjectList läßt, kommt es zu konflikten zwischen den generischen Typen Parametern von TSortObjectList<T> und TCompareItems<T>. Evtl solltest Du mal versuchen TCompareItems<T2> anzulegen.

HJay 24. Jan 2013 17:31

AW: Generics.TObjectList<T> mit Compilerfehler URW1111
 
DANKE!

Ja, dann funktioniert es -- aber warum bloß? Und warum sonst nicht? Wenn alles in einer Unit ist, geht es auch auf die ursprüngliche Art (vergleiche die andere Frage).

Danke, es geht auch, wenn man die erste Definition mit T2 und die nächte mit T1 schreibt:
Code:
 TCompareItems<T2> = function(AItem, BItem: T2): Integer of Object;

  TSortObjectList<T1: class> = class(TObjectList<T1>)
    procedure QuickSort(Left, Right: Integer; ACompareMethod: TCompareItems<T1>); overload;
  end;
Was genau hat denn der Compiler-Fehler URW 1111 zu bedeuten? Ist das ein Fehler von mir oder hat der Compiler da einen Fehler?

Darf man als Bezeichner wie "T2" irgendeinen gültigen Bezeichner verwenden? In allen Beispielen wird T genommen, aber scheinbar ist das völlig egal, richtig?

daywalker9 24. Jan 2013 17:41

AW: Generics.TObjectList<T> mit Compilerfehler URW1111
 
Wie man <T> das nun nennt ist egal. Du könntest auch
Delphi-Quellcode:
TObjectList<DeineKlasseDieBenutztWerdenSoll>
schreiben.

In XE3 kommt bei mir acuh diese Meldung, wenn ich den Source von dir so kompiliere:

H2509

Trotzdem solltest Du einen QC Eintrag machen, da ein interner Fehler nicht auftreten sollte. Eigentlich müsste eine ordentliche Fehlermeldung kommen oder kompilieren.

HJay 24. Jan 2013 17:46

AW: Generics.TObjectList<T> mit Compilerfehler URW1111
 
OK, danke, dann weiß ich bescheid.

DANKE!


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:11 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