Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Wertezuweisung an Array der Oberklasse klappt separat, aber nicht als Prozedur (https://www.delphipraxis.net/215476-wertezuweisung-array-der-oberklasse-klappt-separat-aber-nicht-als-prozedur.html)

enigma 11. Jul 2024 12:49

Wertezuweisung an Array der Oberklasse klappt separat, aber nicht als Prozedur
 
Hallo Delphi Community,
es kann sein, dass ich euch für euch einfache Fragen stelle, aber ich freue mich auf eure Tipps 😉

Eine kurze Frage zur Zuweisung von statischen an dynamische Arrays, die als Parameter in der Prozedur als TObject-Arrays deklariert sind.
Delphi-Quellcode:
cArray: Array[0..3] of TUnterklasse;
dynArray: array of TOberklasse;
Ich möchte an dynArray das statische cArray übergeben.
Wird die Wertzuweisung direkt in der Aufrufmethode durchgeführt, klappt es:
Delphi-Quellcode:
  SetLength(dynArray, Length(cArray));
  for i := 0 to High(cArray) do
    dynArray [i] := cArray [i];
In folgender Prozedur wird für aiArray = cArray „Inkompatible Typen“ gemeldet, obwohl der Parameter als Open Array von TObject deklariert ist.
Delphi-Quellcode:
setArrayObj(cArray, dynArray);

procedure setArrayObj(aiArray: array of TObject; var aoArray: TObjectArray); //2024-07-11
var i: Integer;
begin
  SetLength(aoArray, Length(aiArray));
  for i := 0 to High(aiArray) do
    aoArray[i] := aiArray[i];
end;
Vielen Dank für eure Hinweise 😉

Der schöne Günther 11. Jul 2024 13:20

AW: Wertezuweisung an Array der Oberklasse klappt separat, aber nicht als Prozedur
 
Hast du ein komplettes Codebeispiel?
Ich kann jetzt nur raten, aber du kannst dein
Delphi-Quellcode:
cArray: Array[0..3] of TUnterklasse;
halt nicht in ein einen Parameter
Delphi-Quellcode:
aiArray: array of TObject;
reinstecken.

Stell dir das mal umgekehrt vor: Eine Referenz auf ein
Delphi-Quellcode:
Array of TObject
zeigt nun auf ein
Delphi-Quellcode:
Array of TUnterklasse.
. Wer hindert mich jetzt daran, an erster Stelle von meinem Array-Objekt einen
Delphi-Quellcode:
TButton
reinzustecken?
Delphi-Quellcode:
TButton
ist ja auch ein
Delphi-Quellcode:
TObject
. Für das Objekt-Array gültig, aber dem Code, der jetzt mit einem "array of TUnterklasse" arbeitet und einen TButton bekommt, dem flöge das jetzt zur Laufzeit um die Ohren.

Lesestoff zum Thema:

https://de.wikipedia.org/wiki/Kovari..._Kontravarianz

https://delphisorcery.blogspot.com/2...-variance.html

https://codeblog.jonskeet.uk/2013/06...-but-slow-too/

enigma 11. Jul 2024 13:53

AW: Wertezuweisung an Array der Oberklasse klappt separat, aber nicht als Prozedur
 
Alles klar,
danke für deinen Tipp :)

Uwe Raabe 11. Jul 2024 14:12

AW: Wertezuweisung an Array der Oberklasse klappt separat, aber nicht als Prozedur
 
Alternativ könnte man auch auf eine Lösung mit Generics setzen:
Delphi-Quellcode:
type
  TOberklasse = class

  end;

  TUnterklasse = class(TOberklasse)

  end;

var
  cArray: Array[0..3] of TUnterklasse;
  dynArray: TArray<TOberklasse>;

type
  { Da globale generische Methoden nicht erlaubt sind, brauchen wir einen Container. }
  TArrayTools = record
  public
    { Der zweite generische Parameter TSource ist hier als kompatibel zum ersten Parameter T deklariert.
      Damit ist sichergestellt dass die Zuweisung zulässig ist.
      Da das Target-Array eh neu erzeugt wird, halte ich eine function für zweckmäßiger. }
    class function SetArray<T: class; TSource: T>(const ASource: array of TSource): TArray<T>; static;
  end;

class function TArrayTools.SetArray<T,TSource>(const ASource: array of TSource): TArray<T>;
begin
  SetLength(Result, Length(ASource));
  for var I := 0 to Length(ASource) - 1 do
    Result[I] := ASource[I];
end;

procedure Test();
begin
  dynArray := TArrayTools.SetArray<TOberklasse,TUnterklasse>(cArray);
end;

enigma 11. Jul 2024 14:28

AW: Wertezuweisung an Array der Oberklasse klappt separat, aber nicht als Prozedur
 
Vielen Dank Uwe Raabe,

dein Vorschlag mit Generics ist gut - ich habe vor Jahren davon gehört.
Da kommme ich wieder rein :-)


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