AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi for..in Schleifen: Wie in Win32 realisiert?
Thema durchsuchen
Ansicht
Themen-Optionen

for..in Schleifen: Wie in Win32 realisiert?

Ein Thema von choose · begonnen am 26. Sep 2004 · letzter Beitrag vom 26. Sep 2004
Antwort Antwort
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#1

for..in Schleifen: Wie in Win32 realisiert?

  Alt 26. Sep 2004, 19:04
Wie Danny Thorpe in seinem Blogbeitrag New For Loop Syntax beschreibt, John Kaster im BDNtv: Diamondback sneak peek zeigt und hier ua bereits im Thema for-each Schleife in Delphi diskutiert worden ist, soll Diamondback nun Schleifenkonstrukte der Art
for <variable> in <container expression> do <statement>; in Szenarien wie
Delphi-Quellcode:
type
  TMultiArray = array [0..10, 0..3, 0..9] of Integer;

procedure DemoMulti(const table: TMultiArray);
var
  X: Integer;
begin
  for X in table do
    Writeln(x);
end;
aber auch
Delphi-Quellcode:
procedure DemoTStrings(const AStrings: TStrings);
var
  S: string;
begin
  for S in AStrings do
    Writeln(S);
end;
unterstützen.

Während Danny bei Ordinaltypen und Arrays von speziell vom Compiler verarbeiteten, also CompilerMagic, spricht, schweigt sich John über die Realisierung von Klassen (hier: TStrings), die das neue For-Konstrukt unterstützen sollen, aus. Danny schreibt zwar, dass der Containerausdruck
Zitat von danny:
either implements the IEnumerable interface, or implements a pattern that the compiler recognizes as an enumerator, or is a type that the compiler recognizes as being a container of data items, such as an array
und spricht im letzten Fall offensichtlich von Fällen jener Übersetzungsmagie während der erste dem Ansatz in etwa der in Java-Tiger eingeführten Lösung zu entsprechend scheint- unklar hingegen bleibt mir die Aussage, dass
Zitat von Übersetzung der Aussage von Danny:
eine Klasse implementiert ein Muster, das der Compiler als Enumerator erkennt
Wird hier auf die Meta-Ebene gegangen und die Signatur von Methoden auf die Teilbegriffe "Count", "Item" oder sonstigen für Delphi typischen Bezeichnungen für Problemlösungen dieser Art geprüft? Hätte John in seinem Preview nicht explizit gezeigt, dass die Verarbeitung mit TStrings auch unter Win32 funktioniert und erwähnt, dass die VCL generell angepasst wird, um die neue For-Schleife zu unterstützen, hätte ich mich nicht weiter gewundert, nun jedoch stellt sich für mich folgendes Problem:

Mir ist unklar, wie eine Delphi-Win32-Klasse unter Verwendung der besherigen Referenzzählung ein bestimmtes Interface implementieren sollte und ein Objekt dieser Klasse in der oben beschriebenen Form aufgerufen werden kann, ohne dass ein Verringern des Referenzzählers nach Gebrauch auf null zu dessen Freigabe führt!
Beispiel:
Delphi-Quellcode:
var
  MyStrings: TStrings;
  S: string;
begin
  MyStrings := TStringList.Create;
  try
    //...
    for s in MyStrings do // use IEnumerable -> _AddRef
      Writeln(s);
  finally // leave scope of IEnumerable -> _Release -> .Destroy
    FreeAndNil(MyStrings); // tries to destroy object again!
  end;
Weiß jemand von Euch hierzu etwas genaueres und ist die Schnittstelle von IEnumerable bekannt?

Update: Titel des Themas
gruß, choose
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: for..in Schleifen: Wie in Win32 realisiert?

  Alt 26. Sep 2004, 19:08
Ich glaube, da müssen wir noch etwas länger warten, bis das öffentliches Know-How wird

......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Benutzerbild von nailor
nailor

Registriert seit: 12. Dez 2002
Ort: Karlsruhe
1.989 Beiträge
 
#3

Re: for..in Schleifen: Wie in Win32 realisiert?

  Alt 26. Sep 2004, 19:17
in C# sind die sachen, auf die man in einer foreach-schleife zugreift, readonly, d.h. du kannst sie der schleife nicht unterm hintern wegklauen.
Michael N.
http://nailor.devzero.de/code/sharpmath/testing/ --- Tests, Feedback, Anregungen, ... aller Art sehr willkommen!
::: don't try so hard - it'll happen for a reason :::
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#4

Re: for..in Schleifen: Wie in Win32 realisiert?

  Alt 26. Sep 2004, 19:31
Zitat von nailor:
in C# sind die sachen, auf die man in einer foreach-schleife zugreift, readonly, d.h. du kannst sie der schleife nicht unterm hintern wegklauen.
Darum ging es jetzt eigentlich nicht.
@Mieze & Chewie
Kommt IEnumerable nicht erst mit D9 für Delphi32?
Aber zum Problem der etwas hakelig implementierten Pseudo-GC in Delphi32:
Ich habe es schon mehrfach erlebt, dass ein Object erst nach beenden der Methode gelöscht wurde.
Wenn diese Pseudo-GC dann Free anstatt Destroy aufruft wäre ja alles in Butter. (Aus untengenannten Problem habe ich mich mit Interfaces in D32 nicht wirklich ernsthaft befasst. )
BTW: Eine Überarbeitung der Interfaces in Delphi32 wäre langsam mal angebracht. Ich finde es schon ziemlich nervig wenn ir das Objeckt "unter'm Hinter weggeklaut" wird, nur weil man es als Interface ansprechen will.
  Mit Zitat antworten Zitat
Benutzerbild von nailor
nailor

Registriert seit: 12. Dez 2002
Ort: Karlsruhe
1.989 Beiträge
 
#5

Re: for..in Schleifen: Wie in Win32 realisiert?

  Alt 26. Sep 2004, 19:37
Ich dachte, er wollte (unter anderem) wissen, wie verhindert wird, dass die "Sache", die durchlaufen wird, sich während des Schleifendurchlaufs ändert. Und dann wäre das ne Möglichkeit.
Michael N.
http://nailor.devzero.de/code/sharpmath/testing/ --- Tests, Feedback, Anregungen, ... aller Art sehr willkommen!
::: don't try so hard - it'll happen for a reason :::
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: for..in Schleifen: Wie in Win32 realisiert?

  Alt 26. Sep 2004, 19:45
Zitat von Robert_G:
@Mieze & Chewie
Kommt IEnumerable nicht erst mit D9 für Delphi32?
Was anderes hat Chewie auch nicht gefragt

Zitat von Robert_G:
Aber zum Problem der etwas hakelig implementierten Pseudo-GC in Delphi32:
Ich habe es schon mehrfach erlebt, dass ein Object erst nach beenden der Methode gelöscht wurde.
As Designed Intern erstellt Delphi bei der Verwendung von Interfaces einen try...finally...Block, der die Interfaces erst am Ende frei gibt. Das ist meist performanter als diese immer direkt nach ihrer letzten Verwendung frei zu geben.

Zitat von Robert_G:
BTW: Eine Überarbeitung der Interfaces in Delphi32 wäre langsam mal angebracht. Ich finde es schon ziemlich nervig wenn ir das Objeckt "unter'm Hinter weggeklaut" wird, nur weil man es als Interface ansprechen will.
Das kann man selbst, indem man die Methode _Release überschreibt.

......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#7

Re: for..in Schleifen: Wie in Win32 realisiert?

  Alt 26. Sep 2004, 19:49
Zitat von sakura:
...Das kann man selbst, indem man die Methode _Release überschreibt.
Das hättest du mir vor einem Jahr sagen sollen, da hätte ich Interfaces in D32 verdammt gut gebrauchen können.
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#8

Re: for..in Schleifen: Wie in Win32 realisiert?

  Alt 26. Sep 2004, 19:50
Zitat von Robert:
Wäre eine Überarbeitung der Interfaces in Delphi32 langsam mal angebracht
Das werden wir in der kommenden Version von Delphi für Win32 wohl nicht erleben, Änderungen mithilfe eines GC zögen weitreichende Folgen mit sich.
Es könnte jedoch sein, dass sich der Compiler für den Spezialfall der Schleife auf eine Art "GetInterfaceWithoutAffectingRefCount" Nachricht des Objekts beruft, um Methodenzeiger auf die die durch das Interface zu implementierenden Methoden zu bekommen. Technisch möglich wäre dieser Ansatz sogar bei Interfaces, die als Containerausdruck übergeben worden wären.

Doch, selbst wenn die For..In-Schleife keine Referenzzählung durchführen würde, könnte Code der Art
Delphi-Quellcode:
var
  MyObj: TImplementsIEnumerable;
  MyIntf: IEnumerable;
  S: string
begin
  MyObj := TImplementsIEnumerable.Create;
  try
    //..
    for S in MyObj do // references MyObj -> has to be initiated
    begin
      MyIntf := MyObj; // calls _AddRef -> "RefCount" = 1
      MyIntf := nil; //calls _Release -> "RefCount" = 0 -> .Destroy
    end;
  finally
    FreeAndNil(MyObj);
  end;
end;
Sollte im obigen Beispiel MyObj mehr als ein Element besitzen, könnte die Zeile mit dem For-Ausdruck zu Problemen führen, selbst, wenn hier ohne Referenzzähler gearbeitet wird, spätestens aber der Aufruf von FreeAndNil, denn die Zuweisung von nil auf MyIntf hätte das Objekt bereits zerstört!

Für diesen Spezialfall könnte man dem Compiler vielleicht noch eine besondere Prüfung zumuten, so dass For-Schleifen bei einer internen Verwendung doch mit einer Referenzzählung arbeiten. FreeAndNil wie oben aber auch Aufruf von anderen Methoden, die ihrerseits den Referenzzähler verwenden, sind dann wohl aber nur noch unter größtem Aufwand zur Übersetzungszeit als Fehlerquellen erkennbar...

Die angeführten Beispiele zeigen zusammen mit der Idee der Referenz auf Methoden ohne Referenzzählung die von den Delphi-Entwicklern bereits oft als Antwort geltende Idee "Entweder Interfaces oder Objektreferenzen" als denkbare Lösung.
gruß, choose
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#9

Re: for..in Schleifen: Wie in Win32 realisiert?

  Alt 26. Sep 2004, 19:54
Das hängt in diesem Beispiel von der Implementierung des Enumerators an. Bezieht sich dieser auf das TObject von MyObj, dann kann es zu Problemen kommen. Bezieht er sich jedoch auf IEnumerable, so erhöht auch dieser den Referenzzähler um einen

......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#10

Re: for..in Schleifen: Wie in Win32 realisiert?

  Alt 26. Sep 2004, 20:09
Nach meiner Ansicht gibt es für den Compiler, unter Verwendung der spärlichen Informationen von oben, die Möglichkeit
  • "über ein Muster" oder
  • über die Implementierung des Interface IEnumerable
einer Klasse zu entscheiden, ob mit der neuen For-Schleife über ein Objekt iteriert werden kann.

Lassen wir ersteres außer Acht (siehe vorheriges Posting), hat der Compiler die Möglichkeit, über die Tatsache, dass eine Klasse das Interface implementiert, im Fall von oben auch die Möglichkeit, die Tabelle aller implementierten Interfaces zu erfragen (Achtung, dies schließt dann schon dynamische Proxies aus), um eine Referenz auf die Interfacebeschreibung mitsamt Methodentabelle zu erlangen. Es ist es nicht notwendig, Referenzen zu erhöhen, um die so erlangten Referenzen auf Methoden der Art HasNext und GetNext zu verwenden.

Handelt es sich beim Containerausdruck selbst um ein Interface, ist der Aufruf von _AddRef und _Release unproblematisch.
gruß, choose
  Mit Zitat antworten Zitat
Antwort Antwort


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 03:11 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