![]() |
Delphi-Version: XE
"Quelltextbausteine" ähnlich include-Dateien gegen Codedopplung
Hallo,
ich habe mir zur Vereinfachung folgende Methode programmiert:
Delphi-Quellcode:
Das funktioniert aufgrund des Vergleiches leider nur mit der Einschränkung
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;
Delphi-Quellcode:
. 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?
<T: class>
Das einzige, was mir einfällt, ist an einer zentralen Stelle im Programm eine mehrfach überladene Funktion
Delphi-Quellcode:
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...
IsEqual(const FirstValue, SecondValue: T): Boolean;
|
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 |
AW: "Quelltextbausteine" ähnlich include-Dateien gegen Codedopplung
Delphi-Quellcode:
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
TEqualityComparer<T>.Default
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? |
AW: "Quelltextbausteine" ähnlich include-Dateien gegen Codedopplung
Zitat:
Zitat:
|
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.
|
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. |
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:
Arrays haben eine relativ niedrige Abstraktionsebene.
type
TPlayer = record Name:string; Punkte: Integer; ... end; TPlayers = array of TPlayer; 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. |
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. |
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 ;)
|
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. |
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