11 Stimmen

Verwendung generischer Container in Delphi XE - immer?

Generische Container können eine Zeitersparnis darstellen, wenn man ein Element hat und eine stark typisierte Liste dieser Elemente. Es spart die repetitive Codierung der Erstellung einer neuen Klasse mit möglicherweise einer internen TList-Variablen und typisierten Add/Delete-Typ-Methoden, neben anderen Vorteilen (wie all die neuen Funktionalitäten, die durch die generischen Container-Klassen bereitgestellt werden).

Ist es jedoch empfehlenswert, generische Container für stark typisierte Listen immer zu verwenden? Was sind die spezifischen Nachteile dabei? (Wenn man sich keine Sorgen um die Abwärtskompatibilität des Codes macht.) Ich habe gestern eine Serveranwendung geschrieben und hatte eine Liste von Elementen, die ich 'auf die alte Art und Weise' erstellt habe und die ich durch eine generische Liste ersetzen wollte, aber ich entschied mich, es schlank zu halten, größtenteils aus Gewohnheit. (Sollten wir die Gewohnheit brechen und eine neue beginnen, indem wir immer generische Container verwenden?)

1voto

Arnaud Bouchez Punkte 41521

Sie haben über die Abwärtskompatibilität geschrieben... das ist meine größte Sorge, wenn (wie ich) Sie Bibliotheken schreiben, die mit den häufigsten Versionen von Delphi kompilieren sollen.

Auch wenn Sie für ein geschlossenes Projekt nur XE verwenden, erstellen Sie wahrscheinlich einige benutzerdefinierte Bibliotheken, auch wenn Sie den Code nie veröffentlichen. Wir alle haben solche Lieblingsunits zur Hand, einfach verfügbar, um das Rad nicht bei jedem Projekt neu zu erfinden.

In einer zukünftigen Aufgabe müssen Sie möglicherweise alten Code warten, ohne die Möglichkeit zu haben, auf eine neuere Delphi-Version zu aktualisieren (kein Geld für die Migration und Überprüfung von 1.000.000 Codezeilen). In diesem Fall könnten Ihnen Ihre nur für XE erstellten Bibliotheken mit den glänzenden, auf Generics basierenden Listen fehlen...

Aber für eine zu 100% "private" Anwendung, wenn Sie sicher sind, dass Sie niemals alten Delphi-Code warten müssen, sehe ich keinen Grund, Generics nicht zu verwenden. Meine einzige Sorge ist das Problem des vervielfältigten Codes (wie von Mason zitiert): Der CPU-Cache kann mit unnötigem Code gefüllt werden, sodass die Ausführungsgeschwindigkeit leiden könnte. Aber in einer realen Anwendung denke ich, dass Sie keinen Unterschied sehen werden.

Hinweis: Ich habe gerade einige neue Funktionen zu meinem TDynArray-Wrapper hinzugefügt. Ich habe versucht, den Beispielcode von EMB DocWiki nachzuahmen. So könnten Sie generik-ähnliche Funktionen mit guten alten Delphi-Versionen haben... Natürlich sind Generics besser geeignet für die Arbeit mit Klassen, aber mit einigen Arrays und Datensätzen, funktioniert es einfach perfekt!

1voto

Deltics Punkte 21121

Wenn Sie polymorphe Listen benötigen, sind Generics eher ein Hindernis als eine Hilfe. Dies kompiliert nicht einmal, da Sie beispielsweise keine TDogList verwenden können, wenn eine TAnimalList erforderlich ist:

  uses
    Generics.Collections;

  type
    TAnimal = class
    end;

    TDog = class(TAnimal)
    end;

    TAnimalList = TList;
    TDogList = TList;

  procedure FeedTheAnimals(const aList: TAnimalList);
  begin
    // Blah blah blah
  end;

  var
    dogs: TDogList;
  begin
    dogs := TDogList.Create;
    try
      FeedTheAnimals(dogs);

    finally
      dogs.Free;
    end;
  end;

Die Gründe hierfür sind recht klar und leicht zu erklären, aber genauso unlogisch.

Meine eigene Ansicht ist, dass Sie ein paar Sekunden oder Minuten (wenn Sie ein langsamer Tipper sind) sparen können, indem Sie ein generisches Container anstelle eines spezifischeren und geeigneteren Containers erstellen, der Ihren Anforderungen entspricht. Allerdings könnten Sie am Ende mehr Zeit damit verbringen, Probleme und Einschränkungen von Generics zu umgehen, als Sie anfangs gespart haben (und per Definition, wenn Sie bis jetzt keine generischen Container verwendet haben, wissen Sie nicht, welche Probleme/Einschränkungen auftreten können, bis Sie darauf stoßen).

Wenn ich eine TAnimalList benötige, dann besteht die Möglichkeit, dass ich zusätzliche TAnimal-spezifische Methoden auf dieser Listenklasse benötige oder davon profitieren könnte, die ich gerne in einem TDogList erben würde, was wiederum zusätzliche spezifische Elemente einführen könnte, die für seine TDog-Elemente relevant sind.

(Tier und Hund werden nur zu illustrativen Zwecken verwendet, natürlich. Ich arbeite derzeit nicht an Tierarztcode - LOL)

Das Problem ist, dass man das nicht immer von Anfang an weiß.

Defensive Programmierprinzipien legen (für mich, ymmv) nahe, dass es wahrscheinlich teuer werden wird, wenn man sich für ein bisschen Zeitersparnis in die Ecke drängt. Und wenn nicht, ist der zusätzliche "Preis" dafür, die anfängliche Ersparnis nicht zu nutzen, vernachlässigbar.

Außerdem ist Ihr Code mit Benutzern älterer Delphi-Versionen besser teilbar, wenn Sie so großzügig sind.

)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X