Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Prozedur einer Variablen zuweisen (https://www.delphipraxis.net/191444-prozedur-einer-variablen-zuweisen.html)

a.def 17. Jan 2017 12:42

Prozedur einer Variablen zuweisen
 
Ich habe eine grundlegende Frage zu einem Problem.

Statt in einer bestimmten Funktion (Schleife) X-Mal ein Case aufzurufen in welchen entschieden wird ob Func1, Func2 oder Func3 verwendet wird, möchte ich gerne zuvor (vor der Schleife) Func1 2 oder 3 einer Variablen zuweisen.

Von StackOverflow:
Delphi-Quellcode:
interface

type
  TNodeFunction = function(AInput: String): String;

implementation

function Func1(AInput: String): String;
begin
   result := AInput;
end;

function Func2(AInput: String): String;
begin
   result := 'Fooled You';
end;

function Func3(AInput: String): String;
begin
   result := UpperCase(AInput);
end;

procedure Demonstration;
var
  SomeFunc, SomeOtherFunc: TNodeFunction;
begin

     SomeOtherFunc = Func3;

     SomeFunc := Func1;
     SomeFunc('Hello');  // returns 'Hello'
     SomeFunc := Func2;
     SomeFunc('Hello');  // returns 'Fooled You'

     SomeOtherFunc('lower case'); // returns 'LOWER CASE'

end;
Mit dem obigen beispiel funktioniert das wunderbar. Aber was, wenn man Func1 2 oder 3 auch im Unit-Kopf deklariert hat? Wieso funktioniert das dann nicht mehr?
Der Fehler lautet
Zitat:

[dcc32 Fehler] uTest.pas(257): E2009 Inkompatible Typen: 'Reguläre Prozedur und Methodenzeiger'

SProske 17. Jan 2017 12:45

AW: Prozedur einer Variablen zuweisen
 
Delphi-Quellcode:
TNodeFunction = function(AInput: String): String of object;
Müsstest du für Objektmethoden verwenden. Mischen geht IIRC nicht.

a.def 17. Jan 2017 12:54

AW: Prozedur einer Variablen zuweisen
 
Ok davon habe ich jetzt, sagen wir mal, 0 verstanden aber es funktioniert leider nicht.

Ich könnte meine Prozedur auch "nackt" deklarieren, also ohne Deklaration im Kopf aber das macht wieder Arbeit, wenn man Variablen außerhalb benutzen möchte.

SebastianZ 17. Jan 2017 12:58

AW: Prozedur einer Variablen zuweisen
 
Du könntest auch Anonyme Methoden verwenden.
http://docwiki.embarcadero.com/RADSt...oden_in_Delphi

Dadurch kannst du TNodeFunction sowohl eine andere Funktion als auch inline-deklarationen von Funktionen zuweisen (SomeOtherFunc)

Delphi-Quellcode:
interface

type
  TNodeFunction = reference to function(AInput: String): String;

implementation

function Func1(AInput: String): String;
begin
   result := AInput;
end;

function Func2(AInput: String): String;
begin
   result := 'Fooled You';
end;



procedure Demonstration;
var
  SomeFunc, SomeOtherFunc: TNodeFunction;
begin

     SomeOtherFunc := function (AInput: String): String; begin Result := UpperCase(AInput); end;

     SomeFunc := Func1;
     SomeFunc('Hello'); // returns 'Hello'
     SomeFunc := Func2;
     SomeFunc('Hello'); // returns 'Fooled You'

     SomeOtherFunc('lower case'); // returns 'LOWER CASE'

end;

SProske 17. Jan 2017 13:01

AW: Prozedur einer Variablen zuweisen
 
Dann nochmal mit Code - Konsolenanwendung, damit man es schnell nachgebastelt kriegt.

DPR:

Delphi-Quellcode:
program Project1;

uses
  System.SysUtils,
  Unit1 in 'Unit1.pas',
  Unit2 in 'Unit2.pas';

var
  X: TFoo;
begin
  Demonstration;
  WriteLn('');
  X := TFoo.Create;
  try
    X.Demonstration;
  finally
    X.Free;
  end;
  ReadLn;
end.
Unit 1 - direkte Funktionsaufrufe

Delphi-Quellcode:
unit Unit1;

interface

type
  TNodeFunction = function(AInput: String): String;

function Func1(AInput: String): String;
function Func2(AInput: String): String;
function Func3(AInput: String): String;
procedure Demonstration;


implementation

uses
  System.SysUtils;

function Func1(AInput: String): String;
begin
   result := AInput;
end;

function Func2(AInput: String): String;
begin
   result := 'Fooled You';
end;

function Func3(AInput: String): String;
begin
   result := UpperCase(AInput);
end;

procedure Demonstration;
var
  SomeFunc, SomeOtherFunc: TNodeFunction;
begin

     SomeOtherFunc := Func3;

     SomeFunc := Func1;
     WriteLn(SomeFunc('Hello')); // returns 'Hello'
     SomeFunc := Func2;
     WriteLn(SomeFunc('Hello')); // returns 'Fooled You'

     WriteLn(SomeOtherFunc('lower case')); // returns 'LOWER CASE'

end;

end.
Unit 2 - Objektmethoden

Delphi-Quellcode:
unit Unit2;

interface

type
  TNodeFunction = function(AInput: String): String of object;

  TFoo = class
    function Func1(AInput: String): String;
    function Func2(AInput: String): String;
    function Func3(AInput: String): String;
    procedure Demonstration;
  end;

implementation

uses
  System.SysUtils;

procedure TFoo.Demonstration;
var
  SomeFunc, SomeOtherFunc: TNodeFunction;
begin
   SomeOtherFunc := Func3;

   SomeFunc := Func1;
   WriteLn(SomeFunc('Hello')); // returns 'Hello'
   SomeFunc := Func2;
   WriteLn(SomeFunc('Hello')); // returns 'Fooled You'

   WriteLn(SomeOtherFunc('lower case'));
end;

function TFoo.Func1(AInput: String): String;
begin
  result := AInput;
end;

function TFoo.Func2(AInput: String): String;
begin
  result := 'Fooled You';
end;

function TFoo.Func3(AInput: String): String;
begin
  result := UpperCase(AInput);
end;

end.

a.def 17. Jan 2017 13:01

AW: Prozedur einer Variablen zuweisen
 
Danke für die bisherigen Antworten. Leider kommt keine der Lösungen in Frage, da meine Prozeduren im Unit-Kopf deklariert sind und nicht "lose" rumliegen. :(

Kleine aber wichtige Info: meine Prozeduren sind im Unit-Kopf in einer Klasse deklariert.

Delphi-Quellcode:
unit uTest;

interface

uses ... ;

type
 TFunc = procedure(Parameter ...);

type
 TWorkerThread = class(TThread)
 private
  aFunc: TFunc;
  procedure meineProzedur1(Parameter ...);
  procedure meineProzedur2(Parameter ...);
  procedure meineProzedur3(Parameter ...);
 // ...
end;

implementation

procedure TWorkerThread.meineProzedur1(Parameter ...);
begin
end;

procedure TWorkerThread.meineProzedur2(Parameter ...);
begin
end;

procedure TWorkerThread.meineProzedur3(Parameter ...);
begin
end;

procedure TWorkerThread.Execute;
begin
 aFunc := TWorkerThread.meineProzedur2; // <= geht nicht
end;

SebastianZ 17. Jan 2017 13:06

AW: Prozedur einer Variablen zuweisen
 
Du kannst bei Anonymen Methoden sowohl "lose" (inline) als auch deklarierte Methoden (function Func1...) zuweisen (dachte das ist in meinem Beispiel ersichtlich).

himitsu 17. Jan 2017 13:07

AW: Prozedur einer Variablen zuweisen
 
"Lose" heißt doch, dass sie in der Unit rumliegen. :gruebel:
Also entweder im Interface oder nur in der Implementation.

Delphi-Quellcode:
procedure
ist für "lose" Prozeduren/Funktionen, die nicht als Methoden in einem Object/Record liegen.

Delphi-Quellcode:
procedure of object
ist für Methoden und Klassen-Methoden in Objekten.

Delphi-Quellcode:
reference to procedure
ist ein generisches Interface, was alle möglichen Referenzen speichern kann,
also zu Prozeduren/Funktionen, zu Methoden (in Objekten), zu anonymen Methoden und zu Inline-Prozeduren.


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