Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi offenes Array beliebigen Typs als Parameter, so dass es von SetLength akzeptiert wird (https://www.delphipraxis.net/169772-offenes-array-beliebigen-typs-als-parameter-so-dass-es-von-setlength-akzeptiert-wird.html)

RSE 10. Aug 2012 13:40

Delphi-Version: XE

offenes Array beliebigen Typs als Parameter, so dass es von SetLength akzeptiert wird
 
Hallo,

wie kann ich ein offenes Array beliebigen Typs als Parameter übergeben, so dass es von SetLength akzeptiert wird?

Ich habe bereits folgendes probiert:
Delphi-Quellcode:
class procedure TArrays.Remove<T>(var Arr: array of T; Index: Integer);
begin
  if Index < High(Arr) then
    Move(Arr[Index + 1], Arr[Index], SizeOf(Arr[Index]) * (High(Arr) - Index));
  SetLength(Arr, Length(Arr) - 1); // Compiler-Fehlermeldung: "E2008 Inkompatible Typen"
end;
Mit Generics scheint es da also offenbar Probleme zu geben. Wieso es da Probleme gibt, ist mir allerdings unklar.

Bernhard Geyer 10. Aug 2012 13:44

AW: offenes Array beliebigen Typs als Parameter, so dass es von SetLength akzeptiert
 
Geht mit festen Typ?
Ich glaube mich zu erinnern das es da auch nicht geht.

s.h.a.r.k 10. Aug 2012 13:45

AW: offenes Array beliebigen Typs als Parameter, so dass es von SetLength akzeptiert
 
Zitat:

Zitat von RSE (Beitrag 1177728)
Mit Generics scheint es da also offenbar Probleme zu geben. Wieso es da Probleme gibt, ist mir allerdings unklar.

Was genau meinst du damit?

Schon mal folgendes probiert?
Delphi-Quellcode:
class procedure TArrays.Remove<T>(var Arr: TArray<T>; Index: Integer);
begin
  if Index < High(Arr) then
    Move(Arr[Index + 1], Arr[Index], SizeOf(Arr[Index]) * (High(Arr) - Index));
  SetLength(Arr, Length(Arr) - 1);end;
Du versuchst aber nicht zufälligerweise das gleiche wie zu machen? :stupid: Habe hier auch mal einen Record gepostet, über den ich ziemlich viele Array-Methoden abgebildet habe. Mein Record implementiert dabei sehr viele PHP-Methode.

himitsu 10. Aug 2012 13:49

AW: offenes Array beliebigen Typs als Parameter, so dass es von SetLength akzeptiert
 
Offene Array-Parameter können niemals als VAR deklariert werden.

Denn zum Verändern des übergebenen Arrays muß die Übergabe typgenau sein, das hier nicht gegeben ist.


Du kannst aber
Delphi-Quellcode:
xxx<T>(var arr: TArray<T>)
verwenden

RSE 10. Aug 2012 13:53

AW: offenes Array beliebigen Typs als Parameter, so dass es von SetLength akzeptiert
 
Delphi-Quellcode:
var Arr: TArray<T>
funktioniert, vielen Dank! Wieder etwas gelernt...

Edit: Ich kann kein
Delphi-Quellcode:
a: array of Integer
übergeben, sondern nur ein
Delphi-Quellcode:
a: TArray<Integer>
, aber das ist vertretbar, denn TArray ist definiert als:
Delphi-Quellcode:
TArray<T> = array of T
.

Edit2: Klappt super, außer mit
Delphi-Quellcode:
TArray<Pointer>
oder
Delphi-Quellcode:
TArray<TMyRecordType>
... Also etwas genauer:
Delphi-Quellcode:
type
  TProcArray = TArray<Pointer>;
...
procedure UnRegisterEvt(var Evts: TProcArray; Handler: Pointer);
var
  i: Integer;
begin
  i := HandlerIndex(Evts, Handler);
  if i > -1 then
    TArrays.Remove(Evts, i); // Compilerfehler: E2033 Die Typen der tatsächlichen und formalen Var-Parameter müssen übereinstimmen
end;
Delphi ist hier also nicht clever genug, um mitzukriegen, dass als generischer Typ Pointer eingesetzt werden muss. Ich will an dieser Stelle auch nicht Pointer hardcoden, denn dann könnte ich mir die Typdefinition von TProcArray sparen. Bei Klassen gibt es die Methode ClassType von TObject, die den Klassentyp einer Instanz zurückgibt. Kann man irgendwie auch für "normale Variablen" den Typ bestimmen? So etwas wie
Delphi-Quellcode:
TArrays.Remove<TypeOf(Evts[0])>(Evts, i);
würde mir sehr gefallen.

Edit3: Sorry, dass die Edits hier so ausufern...
Delphi-Quellcode:
TArrays.Remove<TypeOf(Evts[0])>(Evts, i);
ist natürlich nicht möglich, da Generics ja zur Compiletime "übersetzt" werden. Ich habe also folgende Änderung gemacht:
Delphi-Quellcode:
type
  TProcFunc = Pointer; // TProc gibt es schon in SysUtils
  TProcFuncArray = TArray<TProcFunc>;
...
    TArrays.Remove<TProcFunc>(Evts, i); // kein Compilerfehler mehr, die Annahme, dass TProcFuncArray ein Array aus TProcFuncs ist, ist denke ich annehmbar.


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