Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Eigene Ableitung von TThreadList<T> - Habe ich einen Denkfehler? (https://www.delphipraxis.net/181360-eigene-ableitung-von-tthreadlist-t-habe-ich-einen-denkfehler.html)

TiGü 8. Aug 2014 13:29

Eigene Ableitung von TThreadList<T> - Habe ich einen Denkfehler?
 
Hallo Gemeinde,

in einer alten Codestelle will ich die
Delphi-Quellcode:
System.Classes.IInterfaceList
bzw.
Delphi-Quellcode:
TInterfaceList
mit einer eigenen generischen Liste ersetzen.

Da der normalen
Delphi-Quellcode:
System.Generics.Collections.TThreadList<T>
einige Methoden fehlen, wollte ich sie durch Ableitung ergänzen.

Wenn ich aber versuche für die Eigenschaft
Delphi-Quellcode:
Items
den Setter
Delphi-Quellcode:
Put
genauso wie in der alten
Delphi-Quellcode:
TInterfaceList
umzusetzen, sagt mir der Compiler, dass der linken Seite nichts zugewiesen werden kann.
Code:
[dcc32 Error] ThreadJob.pas(270): E2064 Left side cannot be assigned to
Siehe folgenden Code, die auskommentierte Stelle ist es.
Delphi-Quellcode:

uses
  System.Generics.Collections;

type
  TGenericThreadList<T> = class(System.Generics.Collections.TThreadList<T>)
  private
    function Get(Index: Integer): T;
    function GetCount: Integer;
    procedure Put(Index: Integer; const Item: T);
    procedure SetCount(const NewCount: Integer);
  public
    function First: T;
    property Count: Integer read GetCount write SetCount;
    property Items[Index: Integer]: T read Get write Put; default;
  end

implementation

uses
  System.RTLConsts;

...

procedure TGenericThreadList<T>.Put(Index: Integer; const Item: T);
var
  LList: TList<T>;
begin
  LList := LockList;
  try
    if (Index < 0) or (Index >= LList.Count) then
      LList.Error(SListIndexError, Index);
//    LList.List[Index] := Item; <--- das schluckt er nicht!
    LList.Items[Index] := Item; // <--- das kompiliert
  finally
    UnlockList;
  end;
end;

...
Wo ist denn da mein Denkfehler?
Wenn man den Typ konkretisiert, also statt T meinetwegen
Delphi-Quellcode:
IInterface
oder
Delphi-Quellcode:
TMeinAuto
, dann geht das.
Ist das ein Bug in XE3?

Dejan Vu 8. Aug 2014 15:12

AW: Eigene Ableitung von TThreadList<T> - Habe ich einen Denkfehler?
 
Na ja. List hat nur einen getter und ist damit read-only. Denke ich.
Deine Threadliste ist in deiner Implementierung ziemlich unperformant, wenn ich das sagen darf. Aber ich vermute, dir kommt es in erster Linie auf Kompatibilität an.

Sir Rufo 8. Aug 2014 15:18

AW: Eigene Ableitung von TThreadList<T> - Habe ich einen Denkfehler?
 
Die Dokumentation Delphi-Referenz durchsuchenSystem.Generics.Collections.TList.List sagt, dass das eine ReadOnly-Property ist. Eigentlich dürften - wenn überhaupt möglich - diese Änderungen gar nicht in der Liste ankommen.

Dejan Vu 8. Aug 2014 15:33

AW: Eigene Ableitung von TThreadList<T> - Habe ich einen Denkfehler?
 
Ich dachte immer,
Delphi-Quellcode:
List[Index] :=Foo
macht etwas anderes, als
Delphi-Quellcode:
List.Insert(Index,Foo
:stupid: Wenn dem so wäre, wäre der Tipp vielleicht suboptimal.

TiGü 8. Aug 2014 15:38

AW: Eigene Ableitung von TThreadList<T> - Habe ich einen Denkfehler?
 
Zitat:

Zitat von Dejan Vu (Beitrag 1268039)
Deine Threadliste ist in deiner Implementierung ziemlich unperformant, wenn ich das sagen darf.

Du darfst das sagen.
Warum ist das so und wie geht es besser?

Sir Rufo 8. Aug 2014 15:38

AW: Eigene Ableitung von TThreadList<T> - Habe ich einen Denkfehler?
 
Zitat:

Zitat von Dejan Vu (Beitrag 1268042)
Ich dachte immer,
Delphi-Quellcode:
List[Index] :=Foo
macht etwas anderes, als
Delphi-Quellcode:
List.Insert(Index,Foo
:stupid: Wenn dem so wäre, wäre der Tipp vielleicht suboptimal.

In Kombination mit vorherigem Remove ;)

Dejan Vu 8. Aug 2014 16:30

AW: Eigene Ableitung von TThreadList<T> - Habe ich einen Denkfehler?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1268044)
In Kombination mit vorherigem Remove ;)

"Dann ist aber der Eintrag nicht mehr an der selben Stelle." sagte Dejan und wunderte sich kurz darauf, wieso die Meute ihn an Füßen und Schultern packte, horizontal hin und her schaukelte, um ihn in hohem Bogen und unter hämischem Johlen, Grölen und Beifallklatschen der Anwesenden die Böschung hinunter zu werfen.

Sir Rufo, der Edle (wie er von seinen Vasalen genannt wird), schüttelte nur augenbrauenwackelnd den Kopf und ritt ins Wochenende.

Dejan, wieder zu sich gekommen, krabbelte die Böschung hinauf, setzte sich wieder hin und schrieb:
Zitat:

Zitat von TiGü (Beitrag 1268043)
Warum ist das so und wie geht es besser?

Du bietest dem Anwender die Möglichkeit, Daten einzeln in die Threadliste zu schreiben (wie man das von einer normalen Liste gewohnt ist). Es besteht also die Gefahr, das er (der Anwender, also ein anderer Programmierer) diese sehr praktische Möglichkeit nutzt, anstatt die anstehenden Änderungen zu sammeln, um sie explizit durch einmaliges Lock/Unlock in die Liste einzutragen.

Die Implementierung der 'Put' Methode ('Set' hat sich eigentlich als Name etabliert, genauergesagt :SetItem', wenn 'Item' der Name der Property ist) an sich ist vollkommen ok.

TiGü 11. Aug 2014 11:12

AW: Eigene Ableitung von TThreadList<T> - Habe ich einen Denkfehler?
 
Zitat:

Zitat von Dejan Vu (Beitrag 1268049)
Zitat:

Zitat von TiGü (Beitrag 1268043)
Warum ist das so und wie geht es besser?

Du bietest dem Anwender die Möglichkeit, Daten einzeln in die Threadliste zu schreiben (wie man das von einer normalen Liste gewohnt ist). Es besteht also die Gefahr, das er (der Anwender, also ein anderer Programmierer) diese sehr praktische Möglichkeit nutzt, anstatt die anstehenden Änderungen zu sammeln, um sie explizit durch einmaliges Lock/Unlock in die Liste einzutragen.

Du meinst ein klassisches AddRange()?
Ja, das wäre noch denkbar.

Dejan Vu 11. Aug 2014 11:38

AW: Eigene Ableitung von TThreadList<T> - Habe ich einen Denkfehler?
 
Ja genau. Dann gibt es zwar immer noch Dumpfbacken, die das nicht verwenden, aber besser wäre das. Ich persönlich würde den Setter weglassen, aber nicht in deinem Fall: Wir reden aber hier ja nicht von einer allgemeinen Threadlist, sondern einem mit möglichst wenig Aufwand zu implementierenden threadsicheren Ersatz für deine Listen und da geht Kompatibilität vor Performance. Erstmal soll es laufen. Den Setter kannst Du dann später irgendwann wegschmeißen und schauen, wie viel Arbeit das Umschreiben wäre...

Ich wollte ja nur darauf hinweisen ;-)

himitsu 11. Aug 2014 11:57

AW: Eigene Ableitung von TThreadList<T> - Habe ich einen Denkfehler?
 
Natürlich könnte man auch direkt LockList und UnlockList aufrufen
und dann kann man ja dennoch problemlos mehrfach etwas in der Liste machen.


CriticalSections sind schneller, als man vielleicht denkt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:58 Uhr.
Seite 1 von 2  1 2   

Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf