Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Gleiche Prozedur mit verschiedenen Parametertypen aufrufen (https://www.delphipraxis.net/162480-gleiche-prozedur-mit-verschiedenen-parametertypen-aufrufen.html)

FriendOfDelphi 24. Aug 2011 13:21

Delphi-Version: 5

Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Hallo Allerseits,

gibt es eigentlich eine Möglichkeit, eine Prozedur mit verschiedenen Parametertypen aufzurufen?
Also eine Prozedur, die z.B. einmal mit einem Parameter vom Typ array of Double, und ein anderes Mal mit einem Typ array of Integer usw. aufgerufen wird.

Das Problem ist, dass die Prozedur eigentlich immer das gleiche macht. Nur mit verschiedenen Arrays.
Delphi-Quellcode:
MeineProzedur(Meinparameter: array of Double);
begin
  //tue was
end;

MeineProzedur(Meinparameter: array of Integer);
begin
  //tue das gleiche
end;
Es wäre doch naheliegend, dass mit einer Prozedur zu machen, der ein "Universaltyp" übergeben wird.
Delphi-Quellcode:
MeineProzedur(Meinparameter: array of "Universal");
begin
  //tue das gleiche
end;
Gibt es da eine Möglichkeit?
Oder muss man damit leben, dass man ein- und dieselbe Prozedur mehrfach für die unterschiedlichen Parametertypen implementiert?

chaosben 24. Aug 2011 13:57

AW: Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Der älteste Weg das zu erreichen, ist einen untypisierten Pointer zu übergeben.
Alternativ ein Record, das alle versch. Typen kennt und ein Feld hat, was angibt, welcher Typ benutzt werden soll.
Alternativ ein Variant.
Alternativ eine Array of Variant.
Alternativ eine Basisklasse und Ableitungen davon.

:-D

sirius 24. Aug 2011 14:00

AW: Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Irgendwo muss die Funktion ja wissen, was du da für Datentypen hast. Auch wenn es für dich in der Hochsprache Pascal gleich aussieht, was du da machst, so ist es im Maschinencode teilweise Welten auseinander. Grade wenn du mit Double oder Integer einfache Rechnenaufgaben löst. Bei Double geht alles durch die FPU, während bei Integer die CPU ausreicht. Es ist also weit unten komplett verschiedener Code.
Jetzt kannst du natürlich verlangen, dass diese Unterscheidung auch noch von der Hochsprache übernommen wird. Das kann man so machen, die meisten Interpretersprachen machen das so. Dazu brauchst du aber trotzdem eine Information über den eigentlichen Variablen-Typ. Dafür wäre Variant (also array of Variant) geeignet. Geht aber mit Performanceeinbußen daher.

s.

himitsu 24. Aug 2011 14:04

AW: Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Es gibt
Delphi-Quellcode:
array of const
, also offener und fast untypisiertes Open-Array-Parameter (siehe Delphi-Referenz durchsuchenFormat)
oder
Delphi-Quellcode:
array of variant
.

Für Beides brauchst du nur eine Prozedur zusammen ... kommt aber darauf an, wie die Parameter übergeben werden sollen.

Werden aber Array-Variablen übergeben, dann kannst/mußt du die beiden Prozeduren so lassen und Diese nur als
Delphi-Quellcode:
overload
deklarieren.

Uwe Raabe 24. Aug 2011 14:39

AW: Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Wenn wirklich das gleiche gemacht wird (was eigentlich?), würde sich eine generische Methode anbieten (ich weiß, Delphi 5, aber darunter geht ja sowieso fast gar nichts).

Delphi-Quellcode:
type
  TMyClass = class
  public
    procedure MeineProzedur<T>(Meinparameter: TArray<T>);
  end;

procedure TMyClass.MeineProzedur<T>(Meinparameter: TArray<T>);
var
  myVar: T;
begin
  for myVar in Meinparameter do
    { tue was auch immer mit myVar }
end;

jaenicke 24. Aug 2011 14:48

AW: Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Was machen denn die Funktionen konkret? Vielleicht gibt es ja eine andere Lösung.

Mit Generics ließe sich sicher viel machen, aber da im Profil D5 steht, fällt das ja flach...

FriendOfDelphi 24. Aug 2011 15:20

AW: Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Zitat:

Zitat von chaosben (Beitrag 1119295)
Der älteste Weg das zu erreichen, ist einen untypisierten Pointer zu übergeben.
Alternativ ein Record, das alle versch. Typen kennt und ein Feld hat, was angibt, welcher Typ benutzt werden soll.
Alternativ ein Variant.
Alternativ eine Array of Variant.
Alternativ eine Basisklasse und Ableitungen davon.

:-D

Die Idee mit dem untypisierten Zeiger gefällt mir am besten.
Nur habe ich ein Problem mit der Typisierung des übergebenen Zeiger.

Ich übergebe einen Zeiger auf eine Variable vom Typ record.
Der Record sieht so aus:
Delphi-Quellcode:
type
  TMeinTyp = record
             Var1: Array [0..10] of SmallInt;
             Var2: Integer;
end;

//...

var
  MeineVar : TMeinTyp;

//...

//Aufruf der Prozedur mit:
MeineProzedur(MeineVar);

//Prozedur
procedure TForm1.MeineProzedur(aArray: Pointer);
begin
  TMeinTyp(aArray^).Var1[index]:=1; //so funktioniert es

  //der Typ "TMeinTyp" ist aber in einer anderen Unit deklariert, die ich nicht verwenden will
  //ich möchte daher direkt auf den "SmallInt"-Teil des Records zugreifen
  //geht das?
  Array [0..6] of SmallInt(aArray^).Var1[index]:=1; //so funktioniert es nicht. Der Compiler meldet: "Anweisung erwartet, aber 'ARRAY' gefunden"
  //mache ich etwas falsch (Syntax), oder funktioniert das nicht?
end;

jaenicke 24. Aug 2011 15:30

AW: Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Das ist doch wohl Blödsinn. Du willst einen allgemeinen Typen übergeben und castest dann doch wieder auf SmallInt?!

Deshalb meine Frage: Was hast du konkret mit den übergebenen Werten vor? An andere Funktionen übergeben, damit rechnen, ...

Uwe Raabe 24. Aug 2011 15:31

AW: Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Du solltest das Design deiner Anwendung überdenken!

FriendOfDelphi 24. Aug 2011 15:56

AW: Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Zitat:

Zitat von jaenicke (Beitrag 1119336)
Das ist doch wohl Blödsinn. Du willst einen allgemeinen Typen übergeben und castest dann doch wieder auf SmallInt?!

Deshalb meine Frage: Was hast du konkret mit den übergebenen Werten vor? An andere Funktionen übergeben, damit rechnen, ...

Na ja ganz so einfach ist es nicht.
Es existieren insgesamt 5 verschiedene Records.

Der Prozedur werden zwei weitere Parameter übergeben:
2.Parameter: eine(Objekt-)Liste und
3.Parameter: Name des übergebenen Tys ("TMeinTyp1", "TMeinTyp2", "TMeinTyp3" usw.)

In dieser Liste werden Werte verwaltet.
In den einzelnen Einträgen der Liste ist gespeichert, aus welchem Rekord(typ) dessen Wert ausgelesen werden soll.

Innerhalb der Prozedur werden nun alle Einträge durchlaufen.
Im jeweiligen Listeneintrag wird verglichen, ob der übergebene Rekord(typ) für den aktuellen Eintrag gültig ist.
Wenn ja, sollen die einzelnen Teile aus dem übergebenen Rekord in dem zugehörigen Listeneintrag gespeichert werden.
Wenn nein, wird die Schleife fortgesetzt.

Wenn für jeden Record eine eigene Prozedur existiert funktioniert das.
Ich möchte aber eine Prozedur für alle Recordtypen haben.

Was ist jetzt daran Blödsinn?

jaenicke 24. Aug 2011 16:25

AW: Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Also ich kann mir zwar noch nicht 100%ig vorstellen was du da machst, aber es hört sich so an als ob du mit Klassen und Vererbung weiterkommen solltest.

Dann kannst du konkrete Klasse einfach als Typ der Basisklasse übergeben. Und du kannst in den abgeleiteten Klassen bestimmte abweichende Funktionalitäten implementieren (überschriebene Methoden, ...), die dann über die Basisklasse aufgerufen werden kann.

Aber wie Uwe Raabe schon sagte:
Ich glaube auch das Problem ist eher das Gesamtkonzept...

Zitat:

Zitat von FriendOfDelphi (Beitrag 1119349)
Was ist jetzt daran Blödsinn?

Damit meinte ich verschiedene Typen zu übergeben und dann den Typ doch wieder zu unterscheiden. Wenn, dann macht eine gemeinsame Prozedur nur Sinn, wenn der größte Teil der Prozedur auch unabhängig vom konkreten Typ funktioniert.

FriendOfDelphi 24. Aug 2011 20:05

AW: Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Zitat:

Zitat von jaenicke (Beitrag 1119355)
Also ich kann mir zwar noch nicht 100%ig vorstellen was du da machst, aber es hört sich so an als ob du mit Klassen und Vererbung weiterkommen solltest.

Dann kannst du konkrete Klasse einfach als Typ der Basisklasse übergeben. Und du kannst in den abgeleiteten Klassen bestimmte abweichende Funktionalitäten implementieren (überschriebene Methoden, ...), die dann über die Basisklasse aufgerufen werden kann.

Aber wie Uwe Raabe schon sagte:
Ich glaube auch das Problem ist eher das Gesamtkonzept...

Zitat:

Zitat von FriendOfDelphi (Beitrag 1119349)
Was ist jetzt daran Blödsinn?

Damit meinte ich verschiedene Typen zu übergeben und dann den Typ doch wieder zu unterscheiden. Wenn, dann macht eine gemeinsame Prozedur nur Sinn, wenn der größte Teil der Prozedur auch unabhängig vom konkreten Typ funktioniert.

Das Problem ist, dass ich mein Programm mit dem eines Kollegen zusammenführen muss. Und der arbeitet halt mit diesen Records, die ich nun benutzen muss.
Um nochmal auf das ursprüngliche Problem zurück zu kommen:
Kann ich denn über ein typcasten auf die einzelnen Teile des Records zugreifen?
Wenn ja, wie ist die richtige Syntax.

hoika 24. Aug 2011 20:37

AW: Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Hallo,

Delphi-Quellcode:
procedure MeineProzedur(Meinparameter: array of Double); overload;
begin
  //tue was
end;

preocedure MeineProzedur(Meinparameter: array of Integer); overload;
begin
  //tue das gleiche
end;
Tue das gleiche kann nicht sein,
es sind 2 verschiedene Arrays.


Heiko

jaenicke 24. Aug 2011 22:38

AW: Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Zitat:

Zitat von FriendOfDelphi (Beitrag 1119417)
Kann ich denn über ein typcasten auf die einzelnen Teile des Records zugreifen?
Wenn ja, wie ist die richtige Syntax.

Ich habe ein wenig gezögert, weil ich nicht sicher bin, ob es sinnvoll ist einen derart grausamen Hack für diesen Fall zu posten... aber ist ja nicht mein Code, in den der Schrott eingebaut wird...
Delphi-Quellcode:
type
  TTestA = record
    a, b: LongInt;
  end;

  TTestB = record
    a: string;
    b: LongInt;
  end;

procedure Test(Value: Pointer);
begin
  ShowMessage(IntToStr(PLongInt(Integer(Value) + 4)^));
end;

var
  a: TTestA;
  b: TTestB;
begin
  a.b := 777;
  b.b := 666;
  Test(@a);
  Test(@b);
end;

Luckie 24. Aug 2011 22:41

AW: Gleiche Prozedur mit verschiedenen Parametertypen aufrufen
 
Wenn er eine Klasse macht, kann er Methoden überladen.


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