Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Warum TStrings erstellen mit TStringList.Create? (https://www.delphipraxis.net/145480-warum-tstrings-erstellen-mit-tstringlist-create.html)

Guido Eisenbeis 2. Jan 2010 14:02


Warum TStrings erstellen mit TStringList.Create?
 
Auszug aus der Turbo-Delphi-Hilfe, Thema "Eine neue Stringliste erstellen":

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var TempList: TStrings; { Liste deklarieren }
begin
  TempList := TStringList.Create; { Listenobjekt erzeugen }
  try   { Stringliste verwenden }
  ...
So Leute, heut bin ich wieder am Grübeln. :gruebel: Immer wieder begegnen mir Codes, in denen Variablen als TStrings deklariert, aber mit TStringList.Create erstellt werden!? In dem obigen Beispiel wird, außer in dem Code-Schnipsel, auch noch im Beschreibungstext explizit darauf hingewiesen:

Code:
So erstellen Sie langlebige Stringlisten:
 
1. Fügen Sie in der Unit-Datei für das Hauptformular Ihrer Anwendung ein Feld des Typs TStrings in die Formulardeklaration ein.

2. ...
Gibt es dafür einen Grund, dass TStringList-en als TStrings deklariert werden? Spricht etwas dagegen, eine TStringList auch mit TStringList zu dekalrieren? Was ist besser? :spin2:

Guido.

Edit: Mir ist bekannt, dass TStrings die Basisklasse, und TStringList davon abgeleitet ist. :smile2:

mkinzler 2. Jan 2010 14:04

Re: Warum TStrings erstellen mit TStringList.Create?
 
TStrings ist die abstrakte Basisklasse von TStringList
Du kannst den Typ natürlich auch alsn TStringList deklariere

himitsu 2. Jan 2010 14:12

Re: Warum TStrings erstellen mit TStringList.Create?
 
Oder besser gesagt: TStrings ist eine abstrakte Basisklasse, welche eine gemeinsame Schnittstelle bietet und selber keine Speicherverwaltung hat.

TStringList ist ein Nachfahre davon ... es gibt noch andere Nachfahren (wie sich z.B. eine hinter .Lines eines TMemo versteckt)



Wenn du selber die TempList nur als TStringList verwendest und sie nicht weitergibst, dann kannst du sie auch direkt als TStringList deklarieren und hast dann auch direkten Zugriff auf spezielle Erweiterungen der TStringList.

s.h.a.r.k 2. Jan 2010 14:16

Re: Warum TStrings erstellen mit TStringList.Create?
 
Ich meine neulich mal etwas bzgl. (Abwärts-)Kompatibilitätsgründen (der Delphi-IDEs) gelesen zu haben, finde es aber leider nicht mehr :gruebel:

Guido Eisenbeis 2. Jan 2010 14:22

Re: Warum TStrings erstellen mit TStringList.Create?
 
Zitat:

Zitat von mkinzler
TStrings ist die abstrakte Basisklasse von TStringList

Hallo Markus. Als hätte ich's geahnt! :mrgreen: Siehe mein "Edit" oben. Deine Antwort kam gerade, als ich den Senden-Button geklickt hab. :hi:


Zitat:

Zitat von mkinzler
Du kannst den Typ natürlich auch alsn TStringList deklariere

Ok, das ist ja schon mal was! Und wie sieht es mit dem oben beschriebenen mischen aus? Warum trifft man das immer wieder mal an?


Zitat:

Zitat von himitsu
Wenn du selber die TempList nur als TStringList verwendest und sie nicht weitergibst, dann kannst du sie auch direkt als TStringList deklarieren und hast dann auch direkten Zugriff auf spezielle Erweiterungen der TStringList.

Hm, ... :gruebel: das ist mir noch nicht ganz klar. Ich verstehe das jetzt mal so, dass man evtl. keine TStringList übergeben kann, wenn TStrings verlangt wird, oder umgekehrt. Aber: Beißt sich da nicht die Katze selbst in den Schwanz, denn wenn man eine als TStrings deklarierte Variable aber beim Instanzieren mit TStringList erstellt, dann ist doch da der Typ festgelegt. Dann kann man das doch auch nicht mehr als TStrings übergeben, oder?


Zitat:

Zitat von s.h.a.r.k
Ich meine neulich mal etwas bzgl. (Abwärts-)Kompatibilitätsgründen (der Delphi-IDEs) gelesen zu haben, finde es aber leider nicht mehr :gruebel:

War mein erster Gedanke, deshalb hab ich mich auch entschlossen zu posten.

Guido.

himitsu 2. Jan 2010 14:23

Re: Warum TStrings erstellen mit TStringList.Create?
 
Zitat:

Zitat von s.h.a.r.k
Ich meine neulich mal etwas bzgl. (Abwärts-)Kompatibilitätsgründen (der Delphi-IDEs) gelesen zu haben, finde es aber leider nicht mehr :gruebel:

Nee nee,

wenn du z.B. diese Prozedur erstellst,
Delphi-Quellcode:
procedure MyProc(List: TStrings);
dann kannst du ihr alle Nachfahren von Strings übergeben.
also z.B. TStringList oder TMemoStrings (die interne virtuelle Stringliste des Memos, mit Umleitung zur Memokomponente von Windows)

Wenn man jetzt sowas macht,
Delphi-Quellcode:
procedure MyProc(List: TStringList);
dann kann man dieser Funktionen nur noch eine TStringList und deren Nachfahren übergeben,
aber z.B. kein Memo.Lines mehr.

Zitat:

Hm, ... Grübelnd... das ist mir noch nicht ganz klar.
TStringList hat ein paar zusätzliche Funktionen, an welche du mit der Variable als TStrings natürlich nur über eine Typumwandlung rankommst.

Guido Eisenbeis 2. Jan 2010 14:48

Re: Warum TStrings erstellen mit TStringList.Create?
 
Zitat:

Zitat von himitsu
Wenn man jetzt sowas macht,
Delphi-Quellcode:
procedure MyProc(List: TStringList);
dann kann man dieser Funktionen nur noch eine TStringList und deren Nachfahren übergeben,
aber z.B. kein Memo.Lines mehr.

So langsam kommt Klarheit in die Sache! Man kann also einen kleinen Eimer (Nachfahre) in einen großen Eimer (Basisklasse) stecken. :mrgreen:

Das hab ich auch gerade getestet. Das eine (TStrings übergeben, wenn TStringList verlangt wird) wird verweigert, während das umgekehrte funktioniert.


Zitat:

Zitat von himitsu
Zitat:

Hm, ... Grübelnd... das ist mir noch nicht ganz klar.
TStringList hat ein paar zusätzliche Funktionen, an welche du mit der Variable als TStrings natürlich nur über eine Typumwandlung rankommst.

Hoppla, gut zu wissen! Also zum Beispiel per TypeCast: TStringList(List).Sort ?

Guido Eisenbeis 2. Jan 2010 14:56

Re: Warum TStrings erstellen mit TStringList.Create?
 
Ok, bleibt immer noch die Ausgangs-Frage: Warum eine Variable als TStrings deklarieren, wenn mit TStringList instanziert wird?

himitsu 2. Jan 2010 14:56

Re: Warum TStrings erstellen mit TStringList.Create?
 
Zitat:

Zitat von Guido Eisenbeis
So langsam kommt Klarheit in die Sache! Man kann also einen kleinen Eimer (Nachfahre) in einen großen Eimer (Basisklasse) stecken. :mrgreen:

Das hab ich auch gerade getestet. Das eine (TStrings übergeben, wenn TStringList verlangt wird) wird verweigert, während das umgekehrte funktioniert.

Jupp, denn TStringList kann alles, was auch TStrings kann (und noch etwas mehr),
darum kann man es auch an alles übergeben, welches TStrings "verlangt"

TString kann nicht alles, welches TStringList kann, darum kann man es auch nicht an etwas übergeben,
welches "mindestens" das verlangt, was auch eine TStringList kann.

thkerkmann 2. Jan 2010 15:13

Re: Warum TStrings erstellen mit TStringList.Create?
 
Dann ist ja wohl TStringlist der größere Eimer :stupid:

Guido Eisenbeis 2. Jan 2010 15:34

Re: Warum TStrings erstellen mit TStringList.Create?
 
Zitat:

Zitat von thkerkmann
Dann ist ja wohl TStringlist der größere Eimer :stupid:

Ja, ja, ich sehe, meine Metapher hinkt gewaltig! :mrgreen:

himitsu 2. Jan 2010 15:40

Re: Warum TStrings erstellen mit TStringList.Create?
 
Code:
Lebewesen > Mensch > Mann > Frank
                          > Daniel
                   > Frau
          > Hund > Pudel
                 > Dackel

var X: Mensch;
  Y: Lebewesen;

Procedure Toilette(Tür: Mann);
In X passen also nur Menschen, Männer und Frauen rein
und in Y dagegen auch noch die Tiere.

Auf dieses Klo dürfen auch NUR die Männer und demnach geht sozusagen Folgendes:
Delphi-Quellcode:
Toilette(Frank);
bei dem
Delphi-Quellcode:
Toilette(Mensch);
könnte es sich eventuell auch um eine Frau handeln und wer möchte denn, daß die uns was abguckt? :zwinker:

Guido Eisenbeis 3. Jan 2010 15:20

Re: Warum TStrings erstellen mit TStringList.Create?
 
@himitsu: Interessant, dass du die "Frau" bei den "Menschen" eingeordnet hast!? *grins* :drunken:

Zitat:

Zitat von Guido Eisenbeis
Man kann also einen kleinen Eimer (Nachfahre) in einen großen Eimer (Basisklasse) stecken.

Zitat:

Zitat von thkerkmann
Dann ist ja wohl TStringlist der größere Eimer :stupid:

Da hat Thomas natürlich recht. Und um meine Metapher anzupassen, formulier ich es mal so:
Ein größerer Eimer (Nachfahre) kann das beinhalten, was ein kleinerer Eimer (Basisklasse) beinhaltet.

Nichtsdestotrotz wieder zurück zum eigentlichen Thema, das immer noch nicht gelöst ist:

Warum eine Variable als TStrings deklarieren, wenn mit TStringList instanziert wird?

Guido.

mkinzler 3. Jan 2010 15:33

Re: Warum TStrings erstellen mit TStringList.Create?
 
Zitat:

Warum eine Variable als TStrings deklarieren, wenn mit TStringList instanziert wird?
Lies dir die Anworten noch einmal durch

Muetze1 3. Jan 2010 15:35

Re: Warum TStrings erstellen mit TStringList.Create?
 
@himitsu: in deinem Beispiel wären "Frank" und "Daniel" aber Instanzen von TMann und nicht Ableitungen. Oder was bilden denn Daniel und Frank denn noch neues aus? Ein viertes Bein? Wenn es natürlich Mutanten sind, dann wären es Ableitungen.

Guido Eisenbeis 3. Jan 2010 15:53

Re: Warum TStrings erstellen mit TStringList.Create?
 
Zitat:

Zitat von mkinzler
Lies dir die Anworten noch einmal durch

So eine "Antwort" erweckt in mir das Gefühl kurz vor dem Veralbertwerden! Ich hoffe, dass das hier nicht der Fall ist. Und um dir zu zeigen, dass ich dir dahingehend Vertrauen geschenkt habe, habe ich tatsächlich die Postings oben noch einmal durchgelesen. Ich kann keine Antwort auf meine Frage erkennen.

Falls ich jedoch blind bin und eine Antwort schlichtweg übersehe, oder du sie erkennen kannst, dann bitte sag sie mir. Und um Missverständnissen vorzubeugen: Bitte nicht in Form von Totschlagargumenten, wie z. B. "wenn du genau kuckst, dann siehst du sie auch" oder "jedem anderen ist das klar" usw. Bitte in einer klaren Form, die ich auch dann verstehe, falls ich wirklich betriebsblind sein sollte!

Guido.

mkinzler 3. Jan 2010 16:02

Re: Warum TStrings erstellen mit TStringList.Create?
 
TStrings ist eine abstrakte Klasse, hierin wird ein (Soll-)Verhalten festgelegt
TStringList ist eine Klasse, die das vorgegebene Verhalten implementiert.
Es gibt aber auch andere Implementierungen (ein Beispiel hat Frank schon genannt)
Wenn man den Typ einer Variablen nun auf TStrings festlegt, kann man hier Referenzen auf Objekte verschiedenster Ableitungen/Implementierungen ablegen; TStringList limitiert auf die eine Implementierungen ( und Nachfahren dieser)

himitsu 3. Jan 2010 16:02

Re: Warum TStrings erstellen mit TStringList.Create?
 
@Muetze1:
Delphi-Quellcode:
TLebewesen = class
  Körper: TFettpolstermitknochen;
  ...
end;

TMann = class(TLebewesen)
  Eier: TSchrumpeldinger;
  Penis: TGlied;
  ...
end;

TFrau = class(TLebewesen)
  Hirn: TSchuhtick;
  Mumu: TSagichnicht;
  ...
end;

TFrank = class(TMann)
  Persönlichkeit: TFranksPersönlichkeit;
  ...
end;
Zitat:

Warum eine Variable als TStrings deklarieren, wenn mit TStringList instanziert wird?
Zitat:

Wenn du selber die TempList nur als TStringList verwendest und sie nicht weitergibst, dann kannst du sie auch direkt als TStringList deklarieren und hast dann auch direkten Zugriff auf spezielle Erweiterungen der TStringList.
Es kommt praktisch in jedem Einzelfall darauf an, was mit der Liste dann alles gemacht und an was sie eventuell übergeben wird.

Guido Eisenbeis 3. Jan 2010 16:04

Re: Warum TStrings erstellen mit TStringList.Create?
 
Zitat:

Zitat von Muetze1
@himitsu: in deinem Beispiel wären "Frank" und "Daniel" aber Instanzen von TMann und nicht Ableitungen. Oder was bilden denn Daniel und Frank denn noch neues aus?

Zum Beispiel die Eigenschaften FaehrtPorsche, IstHetero: Boolean; oder SauftourTermine: Date;

Edit: Schreibfehler korrigiert.

sirius 3. Jan 2010 16:12

Re: Warum TStrings erstellen mit TStringList.Create?
 
Zitat:

Zitat von Guido Eisenbeis
Ok, bleibt immer noch die Ausgangs-Frage: Warum eine Variable als TStrings deklarieren, wenn mit TStringList instanziert wird?

Wenn man direkt folgendes macht:
Delphi-Quellcode:
var x:TStringList;
begin
  x:=TStringlist.create;
 
  ...
end;
und hier x nur als Tstringlist verwendet und niemals nicht
eine andere Klasse (abgeleitet von TStrings) in x verwendet, dann ist es völlig sinnlos TStrings zu nehmen und in der Hilfe auch unsauber erklärt. --> Hier wäre x besser als TStringlist deklariert. Wenn du nirgends Probleme (mit dem Compiler) damit bekommst ist es auch in Ordnung TStringList zu verwenden. Mit TStrings würdest du dir Möglichkeiten verbauen, die vorhanden sind, du aber auf Grund der Deklaration nicht weist wo (Die Möglichkeit der Sortierung hat TStrings IMHO noch nicht dabei etc. pp).


Wo nimmt man nun TStrings?
Möglichkeit 1 (Wurde schon mehrfach hier erwähnt ):
-> Parameter
Du hast eine Methode, welche als Parameter TStrings bekommt
Delphi-Quellcode:
procedure myClass.myMethod(x:TStrings)
begin
  showmessage(x.Strings[0]);
end;
Du kannst in dieser Methode verschiedene Ableitungen von TStrings bekommen und bspw. nur die Strings auslesen und - wie hier - anzeigen. Ob das jetzt eine TStringList ist oder Memostrings oder von einem Stringgrid oder eine eigene Ableitung von TStrings ist völlig egal. Durch die virtualisierung des Getters von Strings wird bei jeder Variante intern eine andere Methode aufgerufen, nur du bekommst immer einen String vom Index 0 zurück.

Möglichkeit 2
-> Unterschiedliche Instanzierung von TStrings
Du bist dir bei der Deklaration noch nicht sicher welche Variante du von TStrings nimmst (das entscheidet sich quasi erst zur Laufzeit):
Delphi-Quellcode:
var x:TStrings;
begin
  if irgendetwas=irgendetwasanders then
    x:=TStringlist.create
  else
    x:=Memo1.lines;
  end;
 
  ...
end;
Hier mal noch ein Beipsiel:
Delphi-Quellcode:
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TmyStrings = class(TStrings)
   protected
    function Get(Index: Integer): string; override;
    function GetCount: Integer; override;
   public
    function Add(const S: string): Integer; override;
    procedure Delete(Index: Integer); override;
    procedure Insert(Index: Integer; const S: string); override;
    procedure Clear; override;
  end;


  TForm1 = class(TForm)
    Memo1: TMemo;
    RadioGroup1: TRadioGroup; //mit 3 Einträgen
    Edit1: TEdit;
    Button1: TButton; //eintragen des Edits in ausgewählte Impl. von TStrings
    Button2: TButton; //Anzeige der Stringlist
    procedure RadioGroup1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
    FStrings:TStrings;
    FmyStrings:TmyStrings;
    FStringList:TStringList;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
  //Übergabe einer konkreten Implementierung an FStrings
  case RadioGroup1.ItemIndex of
    0: FStrings:=Memo1.lines;
    1: FStrings:=FmyStrings;
    2: FStrings:=FStringList;
    else FStrings:=nil;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  //eigentliche Verwendeung von FStrings
  if assigned(FStrings) then
    FStrings.Add(edit1.Text);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  //Anzeige der StringList
  showmessage(FStringlist.Text);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  //ein paar Initialisierungen
  FStringList:=TStringlist.Create;
  FmyStrings:=TmyStrings.Create;
end;


{ TmyStrings }

function TmyStrings.Add(const S: string): Integer;
begin
  //es wird in dem Programm ausschließlich add verwendet
  showmessage(s);
  result:=-1;
end;

procedure TmyStrings.Delete(Index: Integer);
begin //abstrakte Methode überschreiben
end;

function TmyStrings.Get(Index: Integer): string;
begin //abstrakte Methode überschreiben
  raise Exception.create('Keine Strings gespeichert');
end;
function TmyStrings.GetCount: Integer;
begin //abstrakte Methode überschreiben
  result:=0;
end;
procedure TmyStrings.Insert(Index: Integer; const S: string);
begin //abstrakte Methode überschreiben
end;
procedure TmyStrings.Clear;
begin //abstrakte Methode überschreiben
end;

Guido Eisenbeis 3. Jan 2010 16:19

Re: Warum TStrings erstellen mit TStringList.Create?
 
Zitat:

Zitat von mkinzler
Wenn man den Typ einer Variablen nun auf TStrings festlegt, kann man hier Referenzen auf Objekte verschiedenster Ableitungen/Implementierungen ablegen; TStringList limitiert auf die eine Implementierungen ( und Nachfahren dieser)

Jetzt bin ich mir unsicher. Ich denke, ich stehe wirklich auf dem Schlauch. :oops:

Ok, nochmal zum Verständnis:

Wenn ich eine Variable mit der Basisklasse deklariere, bleiben mir Möglichkeiten offen, die mit eine Nachfolgerklasse schon festgelegt sind. Soweit klar. Meine Fragestellung beinhaltet aber auch, dass ich von vornherein vorhabe, die Variable mit TStringList zu instanzieren. Ist das geschehen, (und das ist ja hier das Thema) kann ich die Kasse TString doch nicht mehr nutzen!?

Oder meinst du vielleicht, dass man die Variable leert (TStringList.Free) und dann eine andere (Nachfolger-)Klasse instanziert?

Bin ich jetzt auf dem richtigen Weg, oder liege ich jetzt ganz daneben?

mkinzler 3. Jan 2010 16:22

Re: Warum TStrings erstellen mit TStringList.Create?
 
Wie gesagt, wenn du Objekte von TStringList erzeugen/ablegen willst ist auch TStringList als Typ ok

himitsu 3. Jan 2010 16:25

Re: Warum TStrings erstellen mit TStringList.Create?
 
Zitat:

Zitat von Guido Eisenbeis
Ist das geschehen, (und das ist ja hier das Thema) kann ich die Kasse TString doch nicht mehr nutzen!?

doch

Wenn die Klasse als TStrings deklariert ist, hast du aber über die Variable nur direkten Zugriff auf die Anteile der TStrings-Schnittstelle.
Sortieren kann man dann also nicht mehr.


Handhabe es einfach so:

- Variablendeklarationen so hoch wie möglich, denn dann hast du direkten Zugriff auf alle Möglichkeiten der instantitierten Klasse
> also TStringList

- Parameterdeklarationen so klein wie möglich, dann hast du die größte Kompatibilität zu anderen Ableitungen
> also TStrings

Guido Eisenbeis 3. Jan 2010 16:32

Re: Warum TStrings erstellen mit TStringList.Create?
 
Wow! Danke für die Antworten! Bitte um Geduld, das muss ich jetzt erst verdauen und testen. Melde mich dann wieder.

Guido.

Edit: Gemeint sind alle Antworten ab Posting #20 von sirius. Will damit sagen, dass ich keinen vergessen habe, sondern am abarbeiten bin!
Edit 2: Hab tatsächlich noch welche übersehen, muss also heißen: Alle Antworten ab Posting #17 von mkinzler.

Guido Eisenbeis 3. Jan 2010 17:53

Re: Warum TStrings erstellen mit TStringList.Create?
 
Mann oh Mann, ganz schön viel Zeugs! Ich versuche das mal möglichst kurz zusammen zu fassen. (Wird wohl trozdem ein bisschen länger :-D )

Zitat:

Zitat von sirius
Wenn man direkt folgendes macht:
Delphi-Quellcode:
var x:TStringList;
begin
  x:=TStringlist.create;
 
  ...
end;
und hier x nur als Tstringlist verwendet und ..., dann ist es völlig sinnlos TStrings zu nehmen und in der Hilfe auch unsauber erklärt.
...
Mit TStrings würdest du dir Möglichkeiten verbauen, die vorhanden sind, ...

Nach allem was ich jetzt so durchblicke, ist das in der Hilfe schon dicht an einem Bug, oder? Denn wie sirius und weiter unten auch himitsu (ist das Frank?) schreiben, sind dann die Möglichkeiten von TStringList nicht mehr vorhanden! (Hab ich selbstverständlich getestet.)

Zitat:

Zitat von sirius
Wo nimmt man nun TStrings?
Möglichkeit 1 (Wurde schon mehrfach hier erwähnt ):
-> Parameter
Du hast eine Methode, welche als Parameter TStrings bekommt

Ist klar, ist aber ein anderes Thema.

Zitat:

Zitat von sirius
Möglichkeit 2
-> Unterschiedliche Instanzierung von TStrings
Du bist dir bei der Deklaration noch nicht sicher welche Variante du von TStrings nimmst (das entscheidet sich quasi erst zur Laufzeit)

Auch klar, auch ein anderes Thema. In diesem Thema geht es darum, dass TStringList gebraucht wird. Und die Deklaration in der Hilfe als TStrings deshalb auch als Bug anzusehen ist, denn man kann ja die Methoden und Eigenschaften von TStringList nicht nutzen (wie z. B. Sort).

Hier kristallisiert sich jetzt auch eine andere Formulierung der Ausgangsfrage herraus. Denn mit zunehmenden Informationen scheint es mir immer unsinniger, eine TString-Variable mit TStringList.Create zu instanzieren. In einem Beispiel von sirius verzweigt er zwar in einer Abfrage nach TStringlist.create,

Delphi-Quellcode:
var x:TStrings;
begin
  if irgendetwas=irgendetwasanders then
    x:=TStringlist.create   // <-- hier
  else
    x:=Memo1.lines;
  end;
aber wirklich Sinn macht es doch nicht, da nur die Eigenschaften und Methoden von TStrings verwendet werden können. Es kann an der obigen Stelle doch mit was-weiß-ich-was instanziert werden, es bleibt doch immer nur TStrings verfügbar. Oder sehe ich das falsch?

Zitat:

Zitat von himitsu
Wenn du selber die TempList nur als TStringList verwendest und sie nicht weitergibst, dann kannst du sie auch direkt als TStringList deklarieren ...

Soweit ich das jetzt verstanden und getestet habe, ist es egal, als was man "TempList" deklariert oder instanziert hat. Es ist bei Weitergeben nur wichtig, welchen Datentyp der Parameter der Weitergabe-Routine hat. Ist zum Beispiel in der Routine der Parameter mit TStringList deklariert, meine Variable vorher mit TStrings deklariert und mit TStringList.Create instanziert, wirft der Compiler Fehler, wegen inkompatiblen Typen.

Zitat:

Zitat von himitsu
... kannst du sie auch direkt als TStringList deklarieren und hast dann auch direkten Zugriff auf spezielle Erweiterungen der TStringList.

Das finde ich einen wichtigen Punkt, der in der Hilfe fehlt! Denn wenn man nun das hier alles nicht weiß, in seinem Programm eine Variable mit TStrings deklariert und mit TStringList instanziert, wundert man sich vielleicht, warum dann z. B. Methoden von TStringList nicht verfügbar sind.

Zitat:

Zitat von mkinzler
TStrings ist eine abstrakte Klasse, hierin wird ein (Soll-)Verhalten festgelegt
TStringList ist eine Klasse, die das vorgegebene Verhalten implementiert.
...
Wenn man den Typ einer Variablen nun auf TStrings festlegt, kann man hier Referenzen auf Objekte verschiedenster Ableitungen/Implementierungen ablegen; TStringList limitiert auf die eine Implementierungen ( und Nachfahren dieser)

Ist klar (und war es auch schon vorher, ... naja, vielleicht nicht so deutlich wie jetzt :oops: ). Das bestätigt doch das was ich von vornherein vermutet habe: Wenn man TStringList haben will, ist eine Deklaration mit TStrings falsch = Fehler in der Delphi-Hilfe.

Zitat:

Zitat von himitsu
Wenn die Klasse als TStrings deklariert ist, hast du aber über die Variable nur direkten Zugriff auf die Anteile der TStrings-Schnittstelle.
Sortieren kann man dann also nicht mehr.

Bestätigt das ebenfalls.

Zitat:

Zitat von himitsu
- Parameterdeklarationen so klein wie möglich, dann hast du die größte Kompatibilität zu anderen Ableitungen
> also TStrings

Dem stimme ich zu.

Zitat:

Zitat von himitsu
- Variablendeklarationen so hoch wie möglich, denn dann hast du direkten Zugriff auf alle Möglichkeiten der instantitierten Klasse
> also TStringList

Das sehe ich genauso. Damit sehe ich die Ausgangsfrage als beantwortet an: Wenn man TStringList mit seinen Eigenschaften und Methoden haben will (und nach meiner Meinung ist das der Fall, wenn man mit TStringList.Create instanziert), dann ist es falsch mit TStrings zu deklarieren.

Puh, geschafft. Vielen Dank an alle für die Antworten! :thumb: Falls ich das Resümee (schreibt man wirklich so) falsch erstellt habe, freue ich mich über Berichtigung. Falls es richtig ist (könnte fast eine if-Abfrage formulieren *smile*) freue ich mich über Bestätigung.

Guido.

PS: Ich hoffe, ich hab da nicht allzuviele Fehler drin, es war jetzt doch ziemlich viel aufzuarbeiten.

mkinzler 3. Jan 2010 18:08

Re: Warum TStrings erstellen mit TStringList.Create?
 
Zitat:

auch himitsu (ist das Frank?)
Ja

Zitat:

eine Deklaration mit TStrings falsch = Fehler in der Delphi-Hilfe.
Ich würde das nicht als Fehler sehen.

Zitat:

Es kann an der obigen Stelle doch mit was-weiß-ich-was instanziert werden, es bleibt doch immer nur TStrings verfügbar. Oder sehe ich das falsch?
Jein. das Objekt( die Instanz) ist schon vom entsprechenden Typ und kennt auch alle Attribute/Methoden/Properties.

Delphi-Quellcode:
var
  sl, sl2: TStrings;
begin
  sl := TStrings.Create;
  sl2 := TStringList.Create;
  (sl2 as TStringList).Sort; //Funktioniert;
  (sl as TStringList).Sort; //Funktioniert nicht, da die Instanz die Methode nicht kennt

Guido Eisenbeis 5. Jan 2010 12:49

Re: Warum TStrings erstellen mit TStringList.Create?
 
Zitat:

Zitat von mkinzler
Zitat:

eine Deklaration mit TStrings falsch = Fehler in der Delphi-Hilfe.
Ich würde das nicht als Fehler sehen.

Nun ja, das ist dann eine Frage der Definition. Ich verstehe schon, was du meinst. Dennoch frage ich mich, warum das hier in der Hilfe gemacht wird. Mir ist außer TStringList kein anderer Fall bekannt, wo in der Hilfe mit einer Basisklasse deklariert, und einer Nachfahrenklasse instanziert wird. Ich lasse mich aber gerne eines Besseren belehren, wenn jemand ein anderes Beispiel in der Hilfe weiß, wo das vorkommt. Denn genauso könnte man, getreu der hier genannten Argumente, dieses Vorgehen bei vielen anderen Klassen anwenden. Das ist mir aber aus der Delphi-Hilfe bei keiner andren Klasse bekannt.

Damit will ich sagen, dass mir trotz der hier erklärten Möglichkeiten (die ich ja auch verstehe) nicht einleuchten will, warum man (gerade) bei TStringList-Instanzierung mit der Basisklasse deklarieren sollte. Ich sehe zwar die hier genannten Möglichkeiten, die sich dadurch ergeben, aber nicht die Notwendigkeit dieser Vorgehensweise. Anders ausgedrückt: Es macht soviel Sinn, wie den Mount Everest zu besteigen. Man kann das tun, ist vielleicht toll, muss man aber nicht.

Weshalb ich von Fehler spreche ist, dass ich es einfach "richtiger" finde, eine Instanz von TStringList auch mit TStringList zu deklarieren. Spätestens nach all den Postings hier finde ich auch keinen Nachteil, der dadurch entstehen würde, und der nicht mit irgendeinem TypeCast zu beheben wäre.


Zitat:

Zitat von mkinzler
Zitat:

Es kann an der obigen Stelle doch mit was-weiß-ich-was instanziert werden, es bleibt doch immer nur TStrings verfügbar. Oder sehe ich das falsch?
Jein. das Objekt( die Instanz) ist schon vom entsprechenden Typ und kennt auch alle Attribute/Methoden/Properties.

Delphi-Quellcode:
var
  sl, sl2: TStrings;
begin
  sl := TStrings.Create;
  sl2 := TStringList.Create;
  (sl2 as TStringList).Sort; //Funktioniert;
  (sl as TStringList).Sort; //Funktioniert nicht, da die Instanz die Methode nicht kennt

Auch für diesen Hinweis vielen Dank! :thumb: Hat mich allerdings auch verwirrt. :drunken: Ich dachte: "Wo fängt das an, wo hört das auf?" Auch der alte Spruch von Toyota fiel mir ein: "Nichts ist un-möööööö-glich, To-yooo-taaa!" Denn irgendwie geht ja (fast) alles.


Zum Schluss sei noch erwähnt:
Zitat:

Zitat von s.h.a.r.k
Ich meine neulich mal etwas bzgl. (Abwärts-)Kompatibilitätsgründen (der Delphi-IDEs) gelesen zu haben, finde es aber leider nicht mehr :gruebel:

Ich halte das in einem gewissen Sinn für möglich. Ich habe in der Hilfe von Delphi 7 nachgesehen und dort steht 1:1 genau das gleiche Beispiel drin. Es beschleicht mich das Gefühl, das da mal irgendwer beim Erstellen der Hilfe vielleicht ungewollt mit TString deklariert und mir TStringList instanziert hat, und das wurde immer und immer wieder übernommen.

Kann jemand mal in einer neueren Delphi-Version nachsehen, ob es dort auch 1:1 übernommen wurde? Es ist zu finden unter dem Thema "Eine neue Stringliste erstellen", Abschnit "Kurzlebige Stringlisten".

Ansonsten: Vielen Dank für all die Postings!

Guido.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:20 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