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
Thema durchsuchen
Ansicht
Themen-Optionen

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
104 Beiträge
 
Delphi 11 Alexandria
 
#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
11.475 Beiträge
 
Delphi 12 Athens
 
#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
719 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
Grüße, 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
Online

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#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
44.184 Beiträge
 
Delphi 12 Athens
 
#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.
$2B or not $2B
  Mit Zitat antworten Zitat
Friday

Registriert seit: 6. Mai 2008
104 Beiträge
 
Delphi 11 Alexandria
 
#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
44.184 Beiträge
 
Delphi 12 Athens
 
#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
$2B or not $2B
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.456 Beiträge
 
Delphi 11 Alexandria
 
#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
Online

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#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
44.184 Beiträge
 
Delphi 12 Athens
 
#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.
$2B or not $2B

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


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 19:28 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