AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi tlist. get "überschreiben", Fehlermeldung verhindern
Thema durchsuchen
Ansicht
Themen-Optionen

tlist. get "überschreiben", Fehlermeldung verhindern

Ein Thema von DrUArn · begonnen am 23. Jul 2012 · letzter Beitrag vom 26. Jul 2012
Antwort Antwort
Seite 2 von 2     12   
DrUArn

Registriert seit: 20. Mär 2003
130 Beiträge
 
Delphi 10.3 Rio
 
#11

AW: tlist. get "überschreiben", Fehlermeldung verhindern

  Alt 24. Jul 2012, 17:11
Hi,
@himitsu: meine obigen Änderungen schlagen wohl alle in das von dir zu vermeidende Kontor.

Diese Gleichsetzung geht tatsächlich.
Ja, meine txyz sind Ableitungen von tobject.

Bis jetzt funktionieren alle Routinen - warum ich mich von tobjectlist wieder abgewendet habe, weiß ich nicht mehr - könnte das aber wieder aufnehmen.

zu Generics - zugegebnermaßen kenne ich diese Schreibweise gar nicht - kann ich auch nicht so schreiben - kommt Fehler tlist<> unbekannt.
Delphi-Quellcode:

type
   TXyzList = class(TList<TXyz>)
     function TryGet(idx: Integer; out obj: TXyz);
   end;

//bei mir
   TMyList1 = class(TList<Tobj1>)
     function TryGet(idx: Integer; out obj: Ttobj1);
//läßt sich nicht kompilieren
Gruß Uwe
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.081 Beiträge
 
Delphi 12 Athens
 
#12

AW: tlist. get "überschreiben", Fehlermeldung verhindern

  Alt 24. Jul 2012, 17:43
Du mußt natürlich noch die passende Unit einbinden.

siehe Delphi-Referenz durchsuchenTObjectList = Unit "Generics.Collections"
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
DrUArn

Registriert seit: 20. Mär 2003
130 Beiträge
 
Delphi 10.3 Rio
 
#13

AW: tlist. get "überschreiben", Fehlermeldung verhindern

  Alt 24. Jul 2012, 17:47
Hi,

ok, mit Generics.collections habe ich mich noch nie beschäftigt.
Bisher habe ich tlist von unit classes verarbeitet!

Generics.collections.tlist kann man den verarbeiteten Zeigertyp festlegen - geht das auch mit Objecten?

Werden diese bei .destroy (.free gibts wohl nicht) mit freigegeben?
In classes.tlist gibt's procedure Notify(Ptr: Pointer; Action: TListNotification); die überschrieben werden kann.

in generics ist das eine Eigenschaft

Fragen über Fragen ...

da Muß ich erst mal 'ne Weile lesen.

Bleibt trotzdem meine Anfrage der abgeleiteten Listen mit abgeleiteten Objekten übrig.

probiert:
tmylist1=class(generics.collections.tobjectlist<tm yobj1>)
end;

nicht erlaubt:
tmylist2=class(generics.collections.tmylist1<tmyob j2>)
end;

man ist also auf den einmalo festgelegten Datentyp festgenagelt - oder?


Gruß Uwe

Geändert von DrUArn (24. Jul 2012 um 17:59 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.081 Beiträge
 
Delphi 12 Athens
 
#14

AW: tlist. get "überschreiben", Fehlermeldung verhindern

  Alt 24. Jul 2012, 19:16
Bei TObjectList ist die Notification schon fertig überschrieben.
Man kann im Constructor oder später über OwnsObjects festlegen, ob die enthaltenen Objekte freigegeben werden sollen.

.Free gibt es immer, denn das ist im Basistyp "TObject" deklatiert, von dem jede Klasse erbt.

Destroy besser nicht direkt aufrufen. (das wird dann intern vom Free aufgerufen)



Nun ja, das ist ja grade der Grund/Vorteil ...
- man muß nicht mehr casten und kann sich dabei auch nicht mehr vertun
- wenn man außerhalb keine "bösen" Casts macht, dann kann man ganz einfach davon ausgehn, daß in der Liste immer nur die vorgegebenen Objekte drinnen sind.

Wie bei der restlichen Vererbung gilt auch hier:
- Es können die angegebenen Typen/Klassen/Objekte in diese Listen rein und alle Nachfahren

Eine TList<xyz> ist also eine Art array of xyz (PS: TArray<xyz> ), mit ein paar mehr Features/Hilfsfunktionen.

Man kann sich dsa teilweise sehr viel sparen. (versuch mal das Selbe mit einer normalen TList + Record-Pointer + New + Dispose + Notify überschreiben oder mit einer TObjectList + TXyz als Objekt, inkl. Create und Co.)
Delphi-Quellcode:
type
  TXyz = record
    s: string;
    i: Integer;
  end;
var
  Liste: TList<TXyz>;
  X: TXyz;
  Z: Integer;
begin
  Liste := TList<TXyz>.Create;
  try
    X.s := 'abc';
    X.i := 123;
    Liste.Add(X);

    X.s := 'def';
    X.i := 456;
    Liste.Add(X);

    X.s := 'xyz';
    X.i := 789;
    Liste.Add(X);

    for Z := 0 to Liste.Count - 1 do
      WriteLn(X[Z].s, X[Z].i);

    for X in Liste do
      WriteLn(X.s, X.i);
  finally
    Liste.Free;
  end;
Den Namespace in generics.collections.tlist kannst du weglassen. (Delphi weiß anhand des <...>, ob generisch oder nicht).

Tipp: Es gibt ganz viele Turorial-Videos bei Emba, Youtube und Co.

Bleibt trotzdem meine Anfrage der abgeleiteten Listen mit abgeleiteten Objekten übrig.
Wie überall halt.
In eine Variable TMemo bekommst du ja auch keine TButton rein. (offiziell und ohne böse Casts)

nicht erlaubt:
Fehlermeldung?
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
DrUArn

Registriert seit: 20. Mär 2003
130 Beiträge
 
Delphi 10.3 Rio
 
#15

AW: tlist. get "überschreiben", Fehlermeldung verhindern

  Alt 24. Jul 2012, 20:25
Hi,
@himitsu:

Danke, ich habe wohl übersehen, das tlist.free nicht automatisch die eingelagerten Elemente und ihren Speicher löscht (?!)
das macht tobjectlist mit Voreinstellung ownsobjecrts=true.

Deiner Anmerkung:
Wie bei der restlichen Vererbung gilt auch hier:
- Es können die angegebenen Typen/Klassen/Objekte in diese Listen rein und alle Nachfahren

kann ich nicht folgen

Delphi-Quellcode:
tmyobj1=class(tobject)
end;

tmyobj2=class(tmyobj1)
end;

TMyList1 = class(TobjectList<tmyobj1>)
end;

TMyList2 = class(TobjectList<tmyobj2>)
end;
ist nicht erlaubt.

nur so:
Delphi-Quellcode:
TMyList2 = class(TobjectList)
end;
da kann ich sicher tmyobj2 durch add einfügen (du schreibst ja, daß das geht), bekomme aber von get oder items[idx] nur tmyobj1,
würde aber gerne in tmylist2 auch auf tmyobj2 zugreifen, welche ich dort speichern möchte.


habe nun folgendes erfolgreich getestet - bleibt die frage, ob das wieder ein böses casting ist
(erst mal für tobjectlist, dürfte aber genauso für die generischen gehen):

Delphi-Quellcode:
TMyList1 = class(TObjectList) {verwaltet tobj1}
  private
  protected
  public
  function Get(Index: Integer): tmyobj1;virtual;//redefiniert die statische Methode, jetzt wird tobj1 statts pointer zurückgegeben
 end;


function TMyList1.Get(Index: Integer): tmyobj1;
begin
result:=inherited get(index);
//if cardinal(index) < Cardinal(Count) then
// Result := List^[Index] else result:=nil;
end;
Wenn ich dafür sorge, das nur tobj1 in die Liste reinkommen, kann ich nun ohne Typcasting auf die Einträge zugreifen, muß
aber für alle Lesezugriffe .get benutzen (nicht etwa .items[idx]) - das ist sicher ein Nachteil.

In einer abgheleiteten Liste mit von tmyobj1 abgeleiteten Elementen und überschriebenem .get könnte ich dann
auf die abgeleiteten Elemente zugreifen und auf die schon vorhandenwen Funktionen von der Vorgängerliste.

Oder ist das auch zu sehr um die Ecke gedacht?

in deinem Beispiel
geht das nicht
for Z := 0 to Liste.Count - 1 do
WriteLn(X[Z].s, X[Z].i); x(z).s gibt's nicht

das ist beeindruckend
for X in Liste do
WriteLn(X.s, X.i);
finally

gibt free hier auch die
Einträge selbst frei???
Liste.Free;


Grüße Uwe

Geändert von DrUArn (24. Jul 2012 um 20:40 Uhr)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#16

AW: tlist. get "überschreiben", Fehlermeldung verhindern

  Alt 24. Jul 2012, 23:47
Ich würde da persönlich jetzt auch eher wie Medium vorgehen, die Exception nicht überschreiben und stattdessen an jeder "top level" Stelle, bei der irgendwie (indirekt) auf get zugegriffen wird, einen Exception Handler per try .. except implementieren. Dadurch kannst du dann im Zweifelsfalle auch ganz konkrete Fehlermeldugen schmeißen.
Ich wollte mit meiner Aussage sogar noch einen Schritt weiter: Warum bekommt der Benutzer überhaupt ungültige Auswahlmöglichkeiten angeboten? Die gehören eliminiert! Dann muss auch nichts getryexcepted werden
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
DrUArn

Registriert seit: 20. Mär 2003
130 Beiträge
 
Delphi 10.3 Rio
 
#17

AW: tlist. get "überschreiben", Fehlermeldung verhindern

  Alt 26. Jul 2012, 12:44
Hi,
nachdem ich noch dies und jenes getestet habe, möchte ich für mich
das Thema abschließen und "Erkenntnisse" zusammenfassen.

1. Ok, mann sollte aus tlist.get die Fehlermeldung nicht rausnehmen
2. Wenn man in tlist Angst vor Fehlgriffen hat, sollte man eine Sicherheitsroutine an kritischen Stellen einrichten alà
Delphi-Quellcode:
function TMyList.ValidIndex(aindex: integer): boolean;
 begin
  result:= cardinal(aindex)<cardinal(Count) //cardinal <-1 ergibt immer eine Zahl größer als cardinal einer positiven Zahl
 end;
3. spezifizierte Listen: Für Speicherung spezieller Datenstrukturen in Listen sind die Generics (tlist<>)bestens geeignet, der Zugriff auf die Elemente ist dann ohne "wilde" Typeumwandlungen möglich - aber

4. Will ich Vererbung sowohl der Elemente als auch der Listen realisieren
komme ich ohne Typumwandlung an irgendeiner Stelle nicht aus:
Delphi-Quellcode:
tmyobj1=class(tobject)
   A:integer;
 end;
 
tmyobj2=class(tmyobj1)
  B:string;
 end;
 
TMyList1withtmyobj1 = class(TobjectList)
    function Get(Index: Integer): tMyobj1;virtual;
    procedure verarbeiteA;
 end;
 
TMyList2withmyobj2 = class(TMyList1withtmyobj1)
   function Get(Index: Integer): tMyobj2;override;
   procedure verarbeiteAundB;
 end;


function TMyList1withtmyobj1.Get(Index: Integer): tmyobj1;
begin
result:=tmyobj1(inherited get(index));
//result:=inherited get(index); ginge auch bei direkten Naschfahren von tlist
end;

function TMyList2withtmyobj2.Get(Index: Integer): tmyobj2;
begin
result:=tmyobj2(inherited get(index));
end;
TMyList2withmyobj2 soll sowohl .verarbeiteA als auch .verarbeiteAundB können.

TMyList1withmyobj1 währe noch generisch am einfachsten, aber danach nicht mehr.

Darum füge ich eine Methode hinzu, die mir die richtigen Objecte liefert, hier überschreibe ich .get.

Ist das dann 'ne "wilde Typumwandlung"?
Der Übergang von tlist nach tobjectlist geht in der Unit cntnrs ähnliche Wege:

Delphi-Quellcode:
function TObjectList.GetItem(Index: Integer): TObject;
begin
  Result := inherited Items[Index];
end;

function TObjectList.First: TObject;
begin
  Result := TObject(inherited First);
end;

//oder gar items selbst
    property Items[Index: Integer]: TObject read GetItem write SetItem; default;

gerade schnell noch probiert:

property Items[Index: Integer]: TMyobj1 read GetItem write SetItem; default;

procedure SetItem(Index: Integer; AObject: tMyObj1);
function GetItem(Index: Integer): TMyObj1;

.
.
.
function TMyList1withtmyobj1.GetItem(Index: Integer): TMyObj1;
begin
Result := TMyObj1(inherited Items[Index]);
end;

procedure TMyList1withtmyobj1.SetItem(Index: Integer; AObject: TMyObj1);
begin
inherited Items[Index] := AObject;
end;


so braucht man .get nicht zu definieren und kann wie gwohnt auf items zugreifen


Danke allen Diskutanten

Grüße Uwe

Geändert von DrUArn (26. Jul 2012 um 13:11 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 04:55 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