Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi System.Collections in Delphi32 einbinden (https://www.delphipraxis.net/96933-system-collections-delphi32-einbinden.html)

GroHae 1. Aug 2007 22:04


System.Collections in Delphi32 einbinden
 
Hallo zusammen,

wenn ich delphi mir z.B. das Composite Muster erstellen lasse, erzeugt er mir diesen Code:
Delphi-Quellcode:
interface

uses System.Collections;  // Fehler // Das ist wohl .NET


type
  TSpeisenkarteKomponente = class abstract
  public
    procedure SampleOperation(i :Integer);virtual;abstract;
    procedure Add(AComponent :TSpeisenkarteKomponente);virtual;
    procedure Remove(AComponent :TSpeisenkarteKomponente);virtual;
    function Components: IEnumerator;virtual; // Fehler
    function GetName: string;
  end;

  TSpeisekarte = class(TSpeisenkarteKomponente)
  strict private var
    ///<associates>TComponent</associates>
    ///  <link>aggregation</link>
    ///  <supplierCardinality>0..*</supplierCardinality>
    FComponentList:ArrayList; // Fehler

  public
    constructor Create;
    procedure SampleOperation(i :Integer);override;
    procedure Add(AComponent :TSpeisenkarteKomponente);override;
    procedure Remove(AComponent :TSpeisenkarteKomponente);override;
    function Components: IEnumerator;override; // Fehler
  end;

  TSpeise = class(TSpeisenkarteKomponente)
  public
    procedure SampleOperation(i :Integer);override;
    function GetName: string;
  end;
So cann ich das nicht kompelieren, da System.Collections anmeckert und dann natürlich IEnumerator und ArrayList nicht kennt.

Wie kann ich System.Collections einbinden?

mkinzler 1. Aug 2007 22:05

Re: System.Collections in Delphi32 einbinden
 
Direkt garnicht, da wie du schon bemerkst hast es sich um eine .Net-Klasse handelt.

alzaimar 2. Aug 2007 05:41

Re: System.Collections in Delphi32 einbinden
 
Du kannst Dir deinen Enumerator selbst basteln um Instanzen der Klasse mit dem 'for in' Konstrukt zu iterieren
Zitat:

Zitat von Die Delphi-Hilfe von BDS
Für die Verwendung von for-in-Schleifenkonstrukten bei Klassen muss die Klasse ein vorschriftsmäßiges Kollektionsmuster implementieren. Ein Typ, der Kollektionsmuster implementiert, muss die folgenden Attribute haben:

Die Klasse muss eine als public deklarierte Instanzmethode namens GetEnumerator() enthalten. Die Methode GetEnumerator() muss einen Klassen-, Interface- oder Record-Typ zurückgeben.
Die von GetEnumerator() zurückgegebene Klasse bzw. das Interface oder der Record muss eine als public deklarierte Instanzmethode namens MoveNext() enthalten. Die Methode MoveNext() muss einen Boolean-Wert zurückgeben.
Die von GetEnumerator() zurückgegebene Klasse bzw. das Interface oder der Record muss eine als public deklarierte, schreibgeschützte Instanzeigenschaft namens Current enthalten. Der Typ der Eigenschaft Current muss mit dem in der Kollektion enthaltenen Typ übereinstimmen.
Wenn der von GetEnumerator() zurückgegebene Enumeratortyp das Interface System.IDisposable implementiert, ruft der Compiler beim Beenden der Schleife die Methode IDisposable.Dispose des Typs auf.


GroHae 2. Aug 2007 06:31

Re: System.Collections in Delphi32 einbinden
 
OK Danke,

das werde ich dann so versuchen.

GroHae 29. Jan 2008 10:10

Ich hab da was noch nicht verstanden
 
Hallo,

jetzt habe ich endlich da weiter gemacht wo ich vor langen aufgehört habe.

Ich habe jetzt folgendes:

Delphi-Quellcode:
interface

uses Classes;


type

  TMyEnumerator = class;

  TSpeisenkarteKomponente = class abstract
  public
    function GetName: string; virtual;
    function GetBeschreibung: string; virtual;
    procedure Ausgeben; virtual;

    procedure Hinzufuegen(AComponent :TSpeisenkarteKomponente);virtual;
    procedure Entfernen(AComponent :TSpeisenkarteKomponente);virtual;
    function GetKind(i:integer) : TSpeisenkarteKomponente; virtual;

    function Components: TMyEnumerator; virtual;
  end;

  // Kompositum
  TSpeisekarte = class(TSpeisenkarteKomponente)
  strict private var
    FComponentList:TList;
  public
    Name, Beschreibung:string;
    constructor Create(iName, iBeschreibung:string);

    function GetName: string; override;
    function GetBeschreibung: string; override;
    procedure Ausgeben; override;

    procedure Hinzufuegen(AComponent :TSpeisenkarteKomponente); override;
    procedure Entfernen(AComponent :TSpeisenkarteKomponente); override;
    function GetKind(i:integer) : TSpeisenkarteKomponente ; override;

    function Components: TMyEnumerator; override;

  end;

  // Blatt
  TSpeise = class(TSpeisenkarteKomponente)
  public
    Name, Beschreibung:string;
    constructor create(iName, iBeschreibung:string);

    function GetName: string; override;
    function GetBeschreibung: string; override;
    procedure Ausgeben; override;
    function Components: TMyEnumerator; override;

  end;


  TMyEnumerator = class
    Values: TList;
    Index: Integer;
  public
    constructor Create(iValues:TList);
    function GetCurrent: TObject;
    function MoveNext:  Boolean;
    property Current:   TObject read GetCurrent;
  end;


implementation

uses SysUtils, Dialogs;

procedure TSpeisenkarteKomponente.Hinzufuegen(AComponent :TSpeisenkarteKomponente);
begin
  ShowMessage('Fehler auslösen');
end;

function TSpeisenkarteKomponente.Components: TMyEnumerator;
begin
  ShowMessage('Fehler auslösen');
  result := nil;
end;

procedure TSpeisenkarteKomponente.Entfernen(AComponent :TSpeisenkarteKomponente);
begin
  ShowMessage('Fehler auslösen');
end;

function TSpeisenkarteKomponente.GetKind(i:integer) : TSpeisenkarteKomponente;
begin
  ShowMessage('Fehler auslösen');
  result := nil;
end;

procedure TSpeisenkarteKomponente.Ausgeben;
begin
  ShowMessage('Fehler auslösen');
end;

function TSpeisenkarteKomponente.GetBeschreibung: string;
begin
  ShowMessage('Fehler auslösen');
  result := '';
end;

function TSpeisenkarteKomponente.GetName: string;
begin
  ShowMessage('Fehler auslösen');
  result := '';
end;

// ================================================================== //

procedure TSpeisekarte.Ausgeben;
begin
  ShowMessage('Karte: ' + GetName + ', ' + GetBeschreibung);
end;

function TSpeisekarte.Components: TMyEnumerator;
begin
  result := TMyEnumerator.Create(FComponentList);
end;

constructor TSpeisekarte.Create(iName, iBeschreibung:string);
begin
  FComponentList := TList.Create;
  Name := iName;
  Beschreibung := iBeschreibung;
end;

procedure TSpeisekarte.Hinzufuegen(AComponent :TSpeisenkarteKomponente);
begin
  FComponentList.Add(AComponent);
end;

procedure TSpeisekarte.Entfernen(AComponent :TSpeisenkarteKomponente);
begin
  FComponentList.Remove(AComponent);
end;

function TSpeisekarte.GetBeschreibung: string;
begin
  result := Beschreibung;
end;

function TSpeisekarte.GetKind(i:integer) : TSpeisenkarteKomponente;
begin
  result := FComponentList.Items[i];
end;

function TSpeisekarte.GetName: string;
begin
  result := Name;
end;

// ================================================================== //


procedure TSpeise.Ausgeben;
begin
  ShowMessage(GetName + ', ' + GetBeschreibung);
end;

function TSpeise.Components: TMyEnumerator;
begin
  result := nil;
end;

constructor TSpeise.create(iName, iBeschreibung:string);
begin
  Name := iName;
  Beschreibung := Beschreibung;
end;


function TSpeise.GetBeschreibung: string;
begin
  result := Beschreibung;
end;

function TSpeise.GetName: string;
begin
  result := Name;
end;


// ================================================================== //

constructor TMyEnumerator.Create(iValues:TList);
begin
  inherited Create;
  Values := iValues;
  Index := -1;
end;

function TMyEnumerator.MoveNext: Boolean;

   // wie soll ich hier über alles Iterieren???? geht doch nicht so oder??
   procedure Recor(iSpeisekarte : TSpeisekarte);
   var
    iti : TMyEnumerator;
   begin
     iti := iSpeisekarte.Components;
     result := iti.MoveNext;
   end;

begin
  if index + 1 < Values.Count then
    begin
      Inc(Index);
      Result := True;
    end
  else
    Result := False;
end;

function TMyEnumerator.GetCurrent: TObject;
begin
  Result := Values[Index];
end;

Test mit:

Delphi-Quellcode:

var
  Karte2 : TSpeisekarte;
  i : integer;

  iti : TMyEnumerator;

begin

  // Speisekarte 1 erstellen
  Karte := TSpeisekarte.Create('=== Karte 1', 'Hauptspeisen');

  //  5 Speisen auf Karte 1
  for i := 1 to 5 do
    Karte.Hinzufuegen(TSpeise.Create('  Ein Artikel ' + inttostr(i), inttostr(i)));

  // Speisekarte 2 erstellen und zur Karte 1 anfügen
  Karte2 := TSpeisekarte.Create('=== Karte 2', 'Nachspeisen');
  Karte.Hinzufuegen(Karte2);

  // 5 Speisen auf Karte 2
  for i := 1 to 5 do
    Karte2.Hinzufuegen(TSpeise.Create('  Ein Artikel von Karte zwei ' + inttostr(i), inttostr(i)));




  iti := Karte.Components;
  while iti.MoveNext do
    Memo1.Lines.Add(TSpeisenkarteKomponente(iti.GetCurrent).GetName);

end;
Als Ausgabe bekomme ich da dann nur
Ein Artikel 1
Ein Artikel 2
Ein Artikel 3
Ein Artikel 4
Ein Artikel 5
=== Karte 2

was mir auch klar ist.

Wie kann ich aber einen Iterator erstellen, der über den ganzen Baum geht?

== Karte 1
Ein Artikel 1
Ein Artikel 2
Ein Artikel 3
Ein Artikel 4
Ein Artikel 5
=== Karte 2
Ein Artikel von Karte zwei 1
Ein Artikel von Karte zwei 2
Ein Artikel von Karte zwei 3
Ein Artikel von Karte zwei 4
Ein Artikel von Karte zwei 5
...


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