Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Array einer Klasse (TRemotable) an procedure geben (https://www.delphipraxis.net/177246-array-einer-klasse-tremotable-procedure-geben.html)

Joerginger 28. Okt 2013 09:03

Array einer Klasse (TRemotable) an procedure geben
 
Hallo Delphianer,

ich hab wieder mal ein (Verständnis)Problem, wie man einer Procedure ein Array einer Klasse übergeben kann... :oops::roll:

Das hab ich (und es funktioniert auch, wobei es wurst ist ob ichs mittels for i löse oder for xy in):
Code:
procedure Kill_aUPD; //Befreit den Speicher von aUPD...

var
  upd:             Update;              //Klasse Update

begin
  for upd in aUpd do upd.Destroy;        //aUPD = Array of Update
  setLength(aUpd,0);
end;


procedure Kill_aArt;  //Befreit den Speicher von aArt

var
  art:             Article;             //Klassse Artikel

begin
  for art in aArt do art.Destroy;        //aART = Array of Artikel
  setLength(aArt,0);
end;
Diese (einzelnen) Routinen gibts für ca. 20 verschiedene Arrays, die sich eben nur durch den Inhalt, sprich - welche Klasse da reinkommt - unterscheidet. Können Artikel, Belege, Adressen, Gruppen, Updates etc. etc. sein...

Und - um das ganze schicker und wartbarer zu gestalten dacht ich mir: Schreibssu eine proc...
Da ich hier auch noch den Typ der Klasse (also Article oder Update übergeben müsste hab ich mir gedacht, machstes mit for i...

Code:
procedure OXKill(aA: xyType);  //Befreit den Speicher von einem beliebigen Array

var
  i:               integer; //Schelfchenvariable

begin
  for I := low(aA to high(aA) do aA[i].Destroy,
  setLength(aA,0);
end;
Da fehlt mir irgendwie der Plan, wie ich dann mittels
Code:
  OXKill(aUpd);
  OXKill(aArt);
ein beliebiges Array übergeben kann, damit das übergebene Array von Klasse XY platt ist... :?:

Was muss ich als xyType angeben, damit der Compiler mich versteht und net so bockig ist mir Typverwechslungen zu unterstellen??? Da's wie in letzter Zeit fast immer um das unselige OXID Webservice geht sind die Klassen TRemotable (falls das wichtig ist).

Danke und GLG,

Erwin J.

DeddyH 28. Okt 2013 09:46

AW: Array einer Klasse (TRemotable) an procedure geben
 
Ohne jetzt groß nachgedacht oder gar ausprobiert zu haben:
Delphi-Quellcode:
type
  TRemotableArray = array of TRemotable;

procedure ClearRemotables(var Remotables: TRemotableArray);
var
  i: integer;
begin
  for i := Low(Remotables) to High(Remotables) do
    Remotables[i].Free;
  Remotables := nil;
end;
Wie gesagt, ob es so funktioniert, kann ich nicht sagen, Versuch macht klug.

Joerginger 28. Okt 2013 09:58

AW: Array einer Klasse (TRemotable) an procedure geben
 
Danke an DeddyH für den Ansatz. Und probiert hab ich weidlich, aber irgendwann dacht' ich mir: ich frag mal die Profis (die's vielleicht sogar wissen :P)

Wenn ich Deinen Code übernehme kömmt:
[DCC Fehler] OXBWOXID.pas(203): E2033 Die Typen der tatsächlichen und formalen Var-Parameter müssen übereinstimmen
[DCC Fehler] OXBWOXID.pas(204): E2033 Die Typen der tatsächlichen und formalen Var-Parameter müssen übereinstimmen

wenn ich das VAR weglasse kömmt:
[DCC Fehler] OXBWOXID.pas(203): E2010 Inkompatible Typen: 'TRemArr' und 'Articles'
[DCC Fehler] OXBWOXID.pas(204): E2010 Inkompatible Typen: 'TRemArr' und 'Updates'

Da der Programmierstil von Dir so schön ist frag ich mal zwischendurch:
Code:
  setLength(Array,0);

  // ist gleichzusetzen mit

  Array := nil;
:?::?:

Und - nicht ganz unwesentlich zum Verständnis... Warum rufst Du nicht .Destroy sondern
Code:
  Array[i].Free;
auf??

Greetz, Erwin J.

DeddyH 28. Okt 2013 10:05

AW: Array einer Klasse (TRemotable) an procedure geben
 
Vermutlich hast Du Deine Arrays als array of Spezifische Klasse deklariert, das müsstest Du ändern auf den selbst deklarierten Typ TRemotableArray. Ggf. führt das aber dazu, dass Du explizit casten müsstest, wenn Du über das Array auf klassenspezifische Methoden oder Properties zugreifst. Den Aufwand kannst nur Du einschätzen. Ob Du die Länge eines dynamischen Arrays auf 0 setzt oder das Array nilst, kommt im Ergebnis auf dasselbe heraus, das ist eher eine Geschmacksfrage. Und zum Free verweise ich mal auf die Hilfe:
Zitat:

Rufen Sie Destroy nicht direkt auf. Verwenden Sie stattdessen Free. Die Methode Free überprüft, ob die Objekt-Referenz nicht bereits nil ist und ruft Destroy nur bei Bedarf auf.

jaenicke 28. Okt 2013 10:19

AW: Array einer Klasse (TRemotable) an procedure geben
 
Zitat:

Zitat von Joerginger (Beitrag 1233388)
[DCC Fehler] OXBWOXID.pas(203): E2010 Inkompatible Typen: 'TRemArr' und 'Articles'
[DCC Fehler] OXBWOXID.pas(204): E2010 Inkompatible Typen: 'TRemArr' und 'Updates'

Dann sind Articles und Updates nicht als TRemArr deklariert.

Zitat:

Zitat von Joerginger (Beitrag 1233388)
Da der Programmierstil von Dir so schön ist frag ich mal zwischendurch:
Code:
  setLength(Array,0);

  // ist gleichzusetzen mit

  Array := nil;
:?::?:

Auf nil setzen ist schneller, da das gleich in einen Aufruf zum Löschen der Inhalte des Arrays kompiliert werden kann, während bei SetLength erst geprüft werden muss welche Elemente gelöscht werden usw.

Zitat:

Zitat von Joerginger (Beitrag 1233388)
Und - nicht ganz unwesentlich zum Verständnis... Warum rufst Du nicht .Destroy sondern
Code:
  Array[i].Free;
auf??

Free prüft vorher, ob der Zeiger nil ist. Das steht auch in der Hilfe:
Zitat:

Rufen Sie Destroy nicht direkt auf. Verwenden Sie stattdessen Free. Die Methode Free überprüft, ob die Objekt-Referenz nicht bereits nil ist und ruft Destroy nur bei Bedarf auf.
http://docwiki.embarcadero.com/Libra...Object.Destroy
Zudem könnte sich dort auch etwas in neueren Delphiversionen ändern (ARC beim Entwickeln für Android mit Delphi ist ein Beispiel), so dass es keinen Sinn macht Destroy direkt aufzurufen.

Joerginger 28. Okt 2013 10:58

AW: Array einer Klasse (TRemotable) an procedure geben
 
Danke, grad wieder Einiges gelernt (Free und so...)...

Zum Hauptthema:
Code:
  Article = class(TRemotable) //Article wird von TRemotalbe abgeleitet
  private
    FOXID: TXSString;
    FOXSHOPID: TXSString;
genauso siehts mit Update, Order, User etc. aus. Immer Ableitungen von TRemotalbe...

und später dann kömmt (da ja ein einzelner Artikel nicht sehr sinnvoll hochzuladen ist
Code:
    Articles  = array of Article;
alternativ dazu werden dann eben Updates = array of Update und so weiter...

Meine Befürchtung ist natürlich jetzt, dass ich so ein Array (weil ja immer unterschiedlich) nicht wirklich übergeben kann?

Greetz, Erwin J.

DeddyH 28. Okt 2013 11:06

AW: Array einer Klasse (TRemotable) an procedure geben
 
Die Befürchtung trifft zu, das sind für Delphi unterschiedliche Typen. Wie schon gesagt wäre die Lösung, den selbstdefinierten Typ TRemotableArray zu verwenden, nur ist das ggf. mit div. Typecasts verbunden.

Joerginger 28. Okt 2013 11:15

AW: Array einer Klasse (TRemotable) an procedure geben
 
Danke, kapiert...

Ich fühl mich nur immer so blöde dabei, wenn ich 20 Routinen quasi kopieren muss (und darin nur eine Variable ändere), statt eine Routine zu pflegen die eben die Variable als Parameter bekommt :cry:

Nach mittlerweile 2 großen Umstellungen in dem Sumpf (und auch deshalb, weil das WebSeitige Modul sich immer wieder noch ändern kann und ich nicht jedesmal das von Delphi erzeugte Service nachbearbeiten will :pale:) enscheide ich mich für die Lösung der 20 Einzelmodule...

Greetz, Erwin J.


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