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 1 von 2  1 2      
DrUArn

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

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

  Alt 24. Jul 2012, 08:34
Hi,

danke für die Antworten.

@Medium: ok, mit Mengen sollte man wohl doch eher nicht arbeiten in diesem Falle, die 255 könnte auch überschritten werden.
@Zacherl: da hatte ich mich schon mal gewundert, daß bei bit-Operationen im negativen Bereich plötzlich 'ne riesen +-Zahl rauskam - that's it!

@ich: der Grund, warum ich .get überschreiben "wöllte" liegt darin, daß ich in tmylist oft Konstrukte wie diesen gebrauche:
Delphi-Quellcode:
{ursprüngliche Version}
function TMyList.GetIndexWert(aindex:integer): integer;
begin
result:=0;
{1} if Cardinal(Index) < Cardinal(Count) then //das ist jetzt schon aus tlist adaptiert
{2}  if Get(aindex)<>nil then
{3}      result:=typumwandlung(get(aindex)).einwert
end;
Wobei ich nun glaube, das {2} nicht nötig ist, wenn ich {1} anwende (doppelt gemoppelt).

bei überschriebenem tmylist.get sieht's so aus
Delphi-Quellcode:
function TMyList.GetIndexWert(aindex:integer): integer;
begin
result:=0;
{2}  if Get(aindex)<>nil then
{3}      result:=typumwandlung(get(aindex)).einwert
end;
wenn ich euch folge und man tmylist.get nicht überschreiben sollte - wie gesagt, falls ein Fehler im ursprünglichen .get entsteht,kommt die Meldung, die den User "nervt" - dann muß ich an allen Stellen, an denen .get genutzt wird, absichern, daß get nicht daneben greift:
Delphi-Quellcode:
function TMyList.GetIndexWert(aindex:integer): integer;
begin
result:=0;
{1}if Cardinal(Index) < Cardinal(Count)
{3}      result:=typumwandlung(get(aindex)).einwert
end;
Also statt in .get in allen Routinen, wo's kritisch werden könnte
"if Cardinal(Index) < Cardinal(Count)" anwenden?

MfG Uwe
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

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

  Alt 24. Jul 2012, 13:15
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.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#3

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

  Alt 24. Jul 2012, 22: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
 
#4

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

  Alt 26. Jul 2012, 11: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 12:11 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

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

  Alt 24. Jul 2012, 14:15
der Grund, warum ich .get überschreiben "wöllte" liegt darin, daß ich in tmylist oft Konstrukte wie diesen gebrauche:
Dann solltest du dir sowas besser abgewöhnen?

Man könnte sich ein TryGet basteln (ähnlich dem Delphi-Referenz durchsuchenTCriticalSection.TryEnter oder Delphi-Referenz durchsuchenTryStrToInt)

Und bezüglich wilder Typumwandlungen ... da haben die Generics ein paar nette Vorteile.

Delphi-Quellcode:
// statt
if MyList.Get(aindex) <> nil then
  Result := TXyz(MyList.Get(aindex)).einwert;

// lieber
if MyList.TryGet(aindex, X) then
  Result := X.einwert;

// oder das, was du eigentlich wissen/prüfen willst
if MyList.Exists(aindex) then
  Result := MyList.Get(aindex).einwert;
Delphi-Quellcode:
type
  TXyzList = class(TList<TXyz>)
    function TryGet(idx: Integer; out obj: TXyz);
  end;

function TXyzList.TryGet(idx: Integer; out obj: TXyz);
begin
  Result := Cardinal(idx) < Cardinal(Count);
  if Result then
    obj := Get(idx);
end;

var
  X: TXyz;
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (24. Jul 2012 um 14:18 Uhr)
  Mit Zitat antworten Zitat
DrUArn

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

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

  Alt 24. Jul 2012, 15:39
Hi,

@Zacherl: Naja, try except kommt mir immer wie Angst vor übersehenen eigenen Fehlern vor
@Himitsu: Habe ich mir heute ähnlich zusammengebastelt - entspricht wohl deinem Vorschlag .exists(idx)
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;
Diese "wilden" Typumwandlungen haben mich auch ständig gestört, hatte aber noch keine Idee dazu.
obj :=Get(idx); kann man obj einfach einen pointer aus .get gleichsetzen?
Muß ich erst mal probieren!
OK - habe ich man darf!
Aber: welchen Vorteil bringt {1} obj :=Get(idx) gegenüber {2}txyz(get(idx)?

Ist {1} nicht auch eine Typumwandlung? Man braucht dann noch eine Variable mehr,
könnte in {2} auch mit with txyz(get(idx)) do arbeiten??

Eigentlich habe ich vor, eine weitere Ableitung von tmylist zu schreiben, die eine Ableitung von vobn txyz speichert.
Also:

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

tmylist1= class(tlist) //enthält tmyobj1

  function tryget(idx:integer; out:tmyobj1):boolean;virtual;
end;

tmyobj2= class(tmyobj1)
...
end;

tmylist2=class(tmylist1) //enthält tmyobj2
  function tryget(idx:integer; out:tmyobj2):boolean;virtual;
end;
Darf man so was - overload???


Danke an die Diskutanten
Gruß Uwe

Geändert von TBx (25. Jul 2012 um 11:43 Uhr) Grund: Delphi-Tag gefixt
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

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

  Alt 24. Jul 2012, 15:50
Gleichsetzen nicht (wenn's ginge, dann wäre das allerdings auch wieder ein wilder Cast), aber ich hatte auch nicht die einfache TList, sondern die generische TList<> verwendet.
Jener gibt man den Typ und sie baut diesen bei allen Aufrufen ein, womit dann nicht Pointer, sondern der richtige Type dort steht.


PS: Das "typumwandlung" ist aber nicht zufällig ein Objekt (Klasse) ?
Wenn ja, dann verwende besser die Delphi-Referenz durchsuchenTObjectList, bzw. TObjectList<> .
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
DrUArn

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

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

  Alt 24. Jul 2012, 16: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.398 Beiträge
 
Delphi 12 Athens
 
#9

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

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

siehe Delphi-Referenz durchsuchenTObjectList = Unit "Generics.Collections"
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
DrUArn

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

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

  Alt 24. Jul 2012, 16: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 16:59 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 16:10 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