Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi "Quelltextbausteine" ähnlich include-Dateien gegen Codedopplung (https://www.delphipraxis.net/170097-quelltextbausteine-aehnlich-include-dateien-gegen-codedopplung.html)

RSE 30. Aug 2012 16:07

Delphi-Version: XE

"Quelltextbausteine" ähnlich include-Dateien gegen Codedopplung
 
Hallo,

ich habe mir zur Vereinfachung folgende Methode programmiert:
Delphi-Quellcode:
class function TArrays.IndexOf<T>(const Arr: TArray<T>; Value: T): Integer;
begin
  for Result := High(Arr) downto 0 do
    if Arr[Result] = Value then
      Exit;
  Result := -1;
end;
Das funktioniert aufgrund des Vergleiches leider nur mit der Einschränkung
Delphi-Quellcode:
<T: class>
. Alle anderen "einfachen" Typen (Integer, String etc.) müsste ich durch überladene Versionen implementieren. Dabei ist der Quelltext im Rumpf der Methode immer identisch, lediglich die Typen im Kopf variieren. Man könnte also den Rumpf in eine Include auslagern, um ihn nicht für jeden weiteren Typ kopieren zu müssen. Allerdings erscheint es mir nicht sinnvoll so einen kleinen Codeschnipsel in eine eigene Datei zu packen. Wenn es eine Art definierbaren "Codebaustein" gäbe, der sich genauso verhält wie eine Include, dann wäre ich glücklich. Allerdings nehme ich an, dass es das nicht gibt. Fällt jemandem eine Alternative außer RTTI ein?

Das einzige, was mir einfällt, ist an einer zentralen Stelle im Programm eine mehrfach überladene Funktion
Delphi-Quellcode:
IsEqual(const FirstValue, SecondValue: T): Boolean;
für alle möglichen Typen bereitzustellen, die ich für solche Zwecke nutzen kann. Das führt allerdings auch zu schwer auffindbaren Fehlern, wenn ich einen Typ verwende, der noch zu keinem überladenen Typ kompatibel ist...

s.h.a.r.k 30. Aug 2012 16:09

AW: "Quelltextbausteine" ähnlich include-Dateien gegen Codedopplung
 
Schau dir mal die Comparer aus den Generics-Units an. Das hilft dir vielleicht bzgl. deinem Vergleich :wink:

[add]
So, habe gerade mal in meiner ArrayHelper-Klasse geschaut:
Delphi-Quellcode:
TComparer<T>.Default;
TEqualityComparer<T>.Default

RSE 30. Aug 2012 16:39

AW: "Quelltextbausteine" ähnlich include-Dateien gegen Codedopplung
 
Delphi-Quellcode:
TEqualityComparer<T>.Default
klingt ungefähr nach dem, was ich suche, aber das arbeitet mit RTTI und das möchte ich nicht. Wieso hat Embarcadero dort nicht für alle Basistypen überladen? Die haben doch den Überblick über all das, was man als normaler Programmierer übersieht. Für referenzierte Typen geht es generisch, und die restlichen sollte man alle (notfalls mit ein wenig Compilermagic) mit kompatiblen Basistypen erschlagen können. Beispielsweise sind ja Aufzählungstypen ordinal -> eine Version für Ordinaltypen würde reichen, ähnlich wie bei
Delphi-Quellcode:
Ord
.

Wenn es sowas nicht gibt, werde ich mich näher mit den Grenzen dessen beschäftigen, was ich selbst in der Richtung machen kann - Kann man irgendwie einen Parametertypen angeben, der typsicher (zwecks Überladen) alle Ordinaltypen akzeptiert und auf Gleichheit prüfen kann?

Uwe Raabe 30. Aug 2012 16:47

AW: "Quelltextbausteine" ähnlich include-Dateien gegen Codedopplung
 
Zitat:

Zitat von RSE (Beitrag 1180726)
Delphi-Quellcode:
TEqualityComparer<T>.Default
klingt ungefähr nach dem, was ich suche, aber das arbeitet mit RTTI und das möchte ich nicht.

Darf man fragen, wieso nicht?


Zitat:

Zitat von RSE (Beitrag 1180726)
Wieso hat Embarcadero dort nicht für alle Basistypen überladen?

Weil die obige Funktion das bereits erledigt?

RSE 30. Aug 2012 16:53

AW: "Quelltextbausteine" ähnlich include-Dateien gegen Codedopplung
 
Ist es nicht so, dass die RTTI einen gewissen Overhead hat, den man nicht bräuchte, wenn man mit überladenen Typen arbeitet? Diese Funktionalität ist bei mir an einer sehr zentralen Stelle und könnte somit durchaus auch in zeitkritischen Programmteilen Verwendung finden. Deshalb möchte ich diese Stelle nicht durch Verwendung von RTTI unnötig ausbremsen.

himitsu 30. Aug 2012 17:56

AW: "Quelltextbausteine" ähnlich include-Dateien gegen Codedopplung
 
Wie bemerkt, kannst du es eben nicht direkt vergleichen, ohne den generischen Parameter nicht auf einen vergleichbaren Typen einzugrenzen.

Also kannst du nur über die RTTI versuchen rauszubekommen, wie man es vergleicht, oder du nutzt den TComparer, bzw. IComparer, welcher es für dich vergleicht.

Delphi-Quellcode:
class function TArrays.IndexOf<T>(const Arr: TArray<T>; Value: T; Comparer: IComparer = nil): Integer;

Wird kein Comparer übergeben, versuchst du einen Default-Comparer zu erstellen und nutzt diesen.

shmia 30. Aug 2012 18:05

AW: "Quelltextbausteine" ähnlich include-Dateien gegen Codedopplung
 
Also ich glaube, Du gehst in die falsche Richtung.
Einerseits scheinst du in deiner Software sehr häufig Arrays von verschiedenen Datentypen einzusetzen.
Ich nehme mal an, dass man in deinem Code solche Deklarationen findet:
Delphi-Quellcode:
type
  TPlayer = record
    Name:string;
    Punkte: Integer;
    ...
  end;
  TPlayers = array of TPlayer;
Arrays haben eine relativ niedrige Abstraktionsebene.
Im Gegensatz zu Objekten sind Arrays völlig ungeschützt; jeder kann lesen & schreiben oder bei dynamischen Arrays die Grösse ändern.
Greift man mit dem Index versehentlich daneben, dann gibt es bei dynamischen Arrays eine Zugriffsverletzung oder ERangeError.

Dabei gibt es neben Arrays auch noch Listen, Queues, Stacks, usw.
Intern können Listen ja durchaus Arrays benützen; entscheidend ist aber wie sich Listen nach aussen "anfühlen".
Der Zugriff auf Listen ist geschützt und die IndexOf()-Methode keine grosse Sache.
Listen sind einfach etwas abstrakter als Arrays.

Arrays sind wie gesagt relativ primitive Datentypen.
Du versuchst diesen Mangel auszugleichen indem du programiertechnisch abeghobene Generics verwendest.
Listen scheinen in deiner Gedankenwelt gar nicht als Alternative zu Arrays zu existieren.
Dabei bist du nicht alleine - es gibt viele Leute hier im Forum, die den Sprung vom Array zur Liste nicht schaffen.

Abstraktionsebenen der Datentypen in Delphi (unvollständige Liste)
1.) ordinale Datentypen, Aufzählungstypen, Boolean, Integer, char, ...
2.) Sets, Arrays fester Grösse
3.) Strings, dynamische Arrays
4.) Records, Events, Variants
5.) Lists, stacks, queues, Trees
6.) Klassen, Objekte
7.) Interfaces, Streams
8.) Design Patterns, Meta Klassen, Generics, Closures, Reflection (=RTTI)
9.) Application Domain, Enterprise Domain Patterns
10.) Systeme, Dienste

Du nimmst also Arrays aus Ebene 3 und vermischst das mit Generics aus Ebene 8.
Dieser Bruch zwischen den Ebenen halte ich für problematisch.
Die Ebene 5 scheint bei Delphi Programmierern ganz allgemein unterrepräsentiert zu sein.

Ok, hier in meinem Beitrag geht es um (Programmier-)Philosophie und falls jemand versuchen sollte Gegenargumente anzubringen werde ich nicht antworten, denn das führt zu nichts.

RSE 30. Aug 2012 18:22

AW: "Quelltextbausteine" ähnlich include-Dateien gegen Codedopplung
 
Wenn ich mit einer Klasse arbeite, die eine Liste repräsentiert, bin ich zwar näher am Paradigma der Objektorientierung, aber kein bisschen weiter. Ich benutze diese Arrays für kleine Aufgaben, die den Aufwand einer eigenen Ableitung einer Liste nicht rechtfertigen. Dort wo ich sie verwende gibt es wesentlich weniger als 20 Quelltextzeilen mit den Arrays (incl. Definition, Parameter in Methodenköpfen etc.). Die Ableitung von TList würde dieses Maß bereits übersteigen. Würde ich mit einer generischen Liste arbeiten, bin ich wieder an der gleichen Stelle, hätte aber den Overhead des Instanzierens und Freigebens. Also bleibe ich für diese Stellen bei einfachen Arrays und halte ein paar Methoden vor, die mir das Leben damit noch mehr vereinfachen. Dadurch gibt es Arrays, die nur in 5 Quelltextzeilen auftauchen.

Im Moment ist das Überladen einer zentralen IsEqual-Funktion immernoch meine präferierte Lösung.

Sir Rufo 31. Aug 2012 00:23

AW: "Quelltextbausteine" ähnlich include-Dateien gegen Codedopplung
 
Wenn du dir eine Factory baust, die eine gewünschte Liste als Interface zurückgibt ist der Aufwand genau gleich wie bei einem Array. Also von daher braucht man sich nicht an den Arrays festklammern ;)

Furtbichler 31. Aug 2012 06:29

AW: "Quelltextbausteine" ähnlich include-Dateien gegen Codedopplung
 
Ich glaube, er will den Overhead und Footprint klein halten. Davon ausgehend, das die eleganten Lösungen seinem Ziel wiedersprechen, bleibt also nur, für jedes Array eine individuelle kleine Routine zu schreiben.

Allerdings scheint mir dann der Ansatz unglücklich, denn das Suchen in einem unsortierten Array ist ziemlich langsam: Je größer die Liste, desto drastischer die Performanceeinbußen.

Um in heterogenen Arrays nach einzelnen Objekten Strukturen zu suchen (ein Primärschlüssel vorausgesetzt), scheint eine Hashmap das Richtige zu sein. Zur Not wäre noch eine THashedStringList eine Möglichkeit, Schlüssel/Struktur-Paare (genauer: Schlüssel/Zeiger-Auf-Struktur-Paare) zum schnellen Suchen zu verwenden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:04 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz