AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Handling von Arrays in einem InterfacedObject

Handling von Arrays in einem InterfacedObject

Ein Thema von Friday · begonnen am 7. Okt 2020 · letzter Beitrag vom 8. Okt 2020
Antwort Antwort
Seite 1 von 2  1 2   
Friday

Registriert seit: 6. Mai 2008
58 Beiträge
 
Delphi XE3 Professional
 
#1

Handling von Arrays in einem InterfacedObject

  Alt 7. Okt 2020, 19:56
Delphi-Version: XE3
Hallo,
ich habe ein Datenpaket welches je nach Situation von unterschiedlichen Objekten analysiert werden soll. In diesem Datenpaket sind mehrere TArray<double> und ein paar Einzelwerte. Die ursprüngliche Idee war dies in einem InterfacedObject zu realisieren und den Objekten die diese Daten analysieren sollen nur das Interface übergeben.

beispielhaft mit nur einem Array:
Delphi-Quellcode:
IDataPackage = Interface(IInterface)
function GetMyArray1: TArray<double>;
procedure SetMyArray1(NewArray: TArray<double>);
property MyArray1: TArray<double> read GetMyArray1 write SetMyArray1;

implementation
...
procedure TSomeObject.AnalyzeData(aDataPackage: IDataPackage);
var tmpAr: TArray<double>;
i: integer;
begin
  tmpAr := aDataPackage.MyArray1;
  for i := 0 to length(tmpAr) do
    // do something with tmpAr[i]
end;
Das macht so einiges an Ärger, da immer wieder StackOverflows passieren.
Die Frage ist, wie macht man das in einer sauberen, unabhängigen und zugleich performanten Objektstruktur?
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
8.000 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Handling von Arrays in einem InterfacedObject

  Alt 7. Okt 2020, 20:09
Da ist ein off-by-one Error:

  for i := 0 to length(tmpAr) - 1 do
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
257 Beiträge
 
Delphi XE5 Professional
 
#3

AW: Handling von Arrays in einem InterfacedObject

  Alt 7. Okt 2020, 20:34
Oder generell, gültig für alle Arrays:
For i:= Low(tmpAr) To High(tmpAr) Do Gruß, Andreas
Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher.
John C. Cornelius
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.091 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Handling von Arrays in einem InterfacedObject

  Alt 7. Okt 2020, 21:11
... wobei ich jetzt nicht erkennen kann, wozu ein Interface sinnvoll ist, wenn es um einen reinen Datenblock ohne eigene Logik geht.

Wäre da nicht ein Record oder eine einfache Klasse einfacher im Handling?

(Ein Argument dafür wäre natürlich die automatische Freigabe wenn der Datenblock nicht mehr in Verwendung ist. Das erkauft man sich dann halt durch die doppelte Deklaration der Klasse und des Interfaces.)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
37.028 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Handling von Arrays in einem InterfacedObject

  Alt 8. Okt 2020, 00:01
Wer weiß was es sonst noch in dem Interface gibt.

Tipp: Im Debugmodus vielleicht auch ab und an mal die Index- und Bereichs-Prüfungen aktivieren.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Friday

Registriert seit: 6. Mai 2008
58 Beiträge
 
Delphi XE3 Professional
 
#6

AW: Handling von Arrays in einem InterfacedObject

  Alt 8. Okt 2020, 08:34
das fehlende "-1" war nur ein Typo hier im Beitrag.

Ja ein Record wäre vermutlich wirklich die beste Lösung in diesem speziellen Fall, da es tatsächlich nur Daten ohne Implementierung benötigt.

Aber rein akademisch bzw. für andere Situationen: Wie greift man performant auf Arrays von einem Objekt zu, dass mittels Interface übergeben wurde?
Für jedes Element über den Getter/Setter des Interface zu gehen ist keine Option.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
37.028 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Handling von Arrays in einem InterfacedObject

  Alt 8. Okt 2020, 09:03
Für jedes Element über den Getter/Setter des Interface zu gehen ist keine Option.
Warum nicht?

Delphi-Arrays:
* erstmal geht sowas natürlich in Delphi (auch wenn man ansonsten zumindestens irgendwie Lesen könnte)
* ohne ShareMem auch nur innerhalb der selben EXE (bei EXE/DLL<->DLL nur wenn mit Laufzeitpackages kompiliert)
* Die Arrays bearbeiten mit einer Referenz mit Referenzzählung, also dein Getter gibt nur einen Zeiger Zurück

* wenn man Daten (Länge, Felder usw.) geändert hat, dann muß man es an den Setter übergeben, um den eventuell geänderten Zeiger zu aktualisieren
** durch einen "Bug" (für mich ist es Einer), gibt es bei dyn. Arrays kein Copy-on-Write, so wie z.B. bei Strings (die intern auch "nur" ein dyn. Array sind)
** bei Änderung eines Chars (beim String ein Array-Element) wird vorher der ganze String kopiert ... bei nomalen dyn. Arrays passiert das nicht

Men könnte ohne Setter arbeiten und über den Getter einen Pointer rausgeben, einen Zeiger auf die Variable,
dann wäre das Array damit komplett verwaltbar (SetLength usw. geht direkt)

Delphi-Quellcode:
B := A;
B[0] := 17; // hier beim Schreibzugriff kein Copy-On-Write
if A[0] = 17 then
Ohne Copy-On-Write wird hier am Getter vorei auch "intern" das Array geändert, weil die Referenzen nicht getrennt werdeb
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
freimatz
Online

Registriert seit: 20. Mai 2010
894 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

AW: Handling von Arrays in einem InterfacedObject

  Alt 8. Okt 2020, 10:11
... wobei ich jetzt nicht erkennen kann, wozu ein Interface sinnvoll ist, wenn es um einen reinen Datenblock ohne eigene Logik geht.

Wäre da nicht ein Record oder eine einfache Klasse einfacher im Handling?

(Ein Argument dafür wäre natürlich die automatische Freigabe wenn der Datenblock nicht mehr in Verwendung ist. Das erkauft man sich dann halt durch die doppelte Deklaration der Klasse und des Interfaces.)
Bei einem Record wird der ganze Speicher kopiert, bei einem interface nur die Referenz.
Ich arbeite gerne beim Datenaustausch mit einer Datenklasse mit interface (DTO). Auf dem interface sind nur getter. Erzeugen kann man nur über eine Constructormethode. Die Datenklasse selber ist versteckt. Die doppelte Deklaration der Klasse wird erleichtert weil wir einen Code-Generator dafür haben. Man muss nur noch das interface selber angeben.

Mit Array haben wir jedoch auch da Schwierigkeiten. Ich tendiere da eher zu IList.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.091 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Handling von Arrays in einem InterfacedObject

  Alt 8. Okt 2020, 12:11
@freimatz
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
37.028 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Handling von Arrays in einem InterfacedObject

  Alt 8. Okt 2020, 13:40
Ich hatte vor 'ner Weile mal mit einer Art "virtuellem" Interface gespielt.
Im Grunde war es ein PRecord (Pointer auf Record), nur das der Pointer in einem Interface versteckt war, samt der Referenzzählung/Speicherverwaltung und automatischem FreeMemory.

> Objekte und Interfaces sind "intern" ja auch "nur" Records, mit einem impliziten Pointer

Aber jetzt, wo Embarcadero es endlich geschaft hat die "Managed Records" einzubauen, welche wir uns seit mindestens 15 Jahren von denen gewünscht hatten,
ist sowas hinfällig und lässt sich schöner bauen > Records mit internem Pointer und automatischer Speicherverwaltung.
Oder man aber eben mit Data-Objekten und kann bei vielen Property auf auch Getter/Setter verzichten.


PS: Egal ob Interface oder Objekt, man kann auch ein Array-Property verwenden, anstatt den direkten Zugriff auf das Array (siehe Lines in der StringList),
dann ist auch eine direkte Zuweisung an ein Item möglich.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu ( 8. Okt 2020 um 13:44 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:47 Uhr.
Powered by vBulletin® Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2020 by Daniel R. Wolf