xsharp.eu • Indirekter Function-Aufruf über einen Delegaten
Page 1 of 2

Indirekter Function-Aufruf über einen Delegaten

Posted: Thu Feb 28, 2019 8:27 am
by pemo18
Hallo Zusammen,

Ich würde gerne eine Art "Funktionsaufruftabelle" implementieren, damit ich Functions über ein Dictionary und einen Schlüssel indirekt aufrufen kann. In C# gibt es dafür Delegaten und die Invoke()-Methode.

In X# habe ich es leider noch nicht geschafft, da ich noch kein Pendant zur Invoke()-Methode gefunden habe.

Hier ist mein kleines Beispiel:

Code: Select all

 
   Delegate funDel() As String
    
    FUNCTION f1 As string
        return "Bewölkt"
   
    FUNCTION f2 As string
        return "Sonne"
   
    FUNCTION f3 As string
        return "Regen"

    FUNCTION Start() AS VOID STRICT
        Local funDic AS Dictionary<int, delegate>
        Local f1del As funDel
        Local f2del As funDel
        Local f3del As funDel
        f1Del := funDel{f1}    
        f2Del := funDel{f2}    
        f3Del := funDel{f3}    
        funDic := Dictionary<int, delegate>{}
        funDic:Add(1, f1del)
        funDic:Add(2, f2del)
        funDic:Add(3, f3del)
        Local z as int
        Local rnd As Random 
        rnd := Random{}
        z := 1
        Local vorhersage as Delegate
        vorhersage := funDic[z]
        Local wetter as string
        wetter := vorhersage
        Console.WriteLine("Die Wettervorhersage für heute: {0}", vorhersage)
        Console.ReadKey()
Meine Frage ist: Wie ich kann ich eine Function über einen Delegaten ausführen?

In der Doku bzw. dem Helpfile habe ich dazu nichts gefunden.

Danke schon einmal im Voraus für einen Tipp und viele Grüße,
Peter

Indirekter Function-Aufruf über einen Delegaten

Posted: Thu Feb 28, 2019 8:41 am
by robert
Peter,

Did you look at: https://www.xsharp.eu/help/lamda-expressions.html
it shows how to call delegates.
Of course in this example the delegates are Lambda expressions, but they can also be the name of a method.
Or try this:

DELEGATE Max(n1 AS INT, n2 AS INT) AS INT
FUNCTION Start AS VOID
LOCAL delMax AS Max
delMax := CalcMax
? delMax (1,2)
? delMax(4,3)
wait
RETURN

FUNCTION CalcMax(n1 AS INT, n2 AS INT) AS INT
IF n1 > n2
RETURN n1
ELSE
RETURN n2
ENDIF

Indirekter Function-Aufruf über einen Delegaten

Posted: Thu Feb 28, 2019 8:59 am
by pemo18
Hello Robert,

Thank you very much. That looks like the missing piece I was looking for.

Kind regards,
Petr

Indirekter Function-Aufruf über einen Delegaten

Posted: Thu Feb 28, 2019 10:19 am
by pemo18
This is the working example that also proves how elegant the X# syntax is:

Code: Select all

Delegate funDel() As String
    
FUNCTION Start() As VOID STRICT
        Local funDic := Dictionary<int, fundel>{} As Dictionary<int, fundel>
        Local f1del := { => "Etwas bewölkter" } As funDel 
        Local f2del := { => "Immer sonniger" } As funDel
        Local f3del := { => "Deutlich regnerischer" } As funDel
        funDic:Add(1, f1del)
        funDic:Add(2, f2del)
        funDic:Add(3, f3del)
        Local z := Random{}:@@Next(1,funDic:Count + 1) As Int
        Console.WriteLine("Die Wettervorhersage für heute: {0}", funDic[z]())
        Console.ReadKey()
Kind regads,
Peter

Indirekter Function-Aufruf über einen Delegaten

Posted: Thu Feb 28, 2019 1:43 pm
by lumberjack
Hi,

Try:

Code: Select all

 
   Delegate funDel() As String
    
    FUNCTION f1 As string
        return "Bewölkt"
   
    FUNCTION f2 As string
        return "Sonne"
   
    FUNCTION f3 As string
        return "Regen"

    FUNCTION Start() AS VOID STRICT
        Local funDic AS Dictionary<int, funDel>
        Local f1del As funDel
        Local f2del As funDel
        Local f3del As funDel
        f1Del := funDel{null, @f1()}    
        f2Del := funDel{null, @f2()}    
        f3Del := funDel{null, @f3()}    
        funDic := Dictionary<int, funDel>{}
        funDic:Add(1, f1del)
        funDic:Add(2, f2del)
        funDic:Add(3, f3del)
        Local z as int
        Local rnd As Random 
        rnd := Random{}
        z := 1
        Local vorhersage as funDel
        vorhersage := funDic[z]
        Local wetter as string
        wetter := vorhersage()
        Console.WriteLine("Die Wettervorhersage für heute: {0}", vorhersage)
        Console.ReadKey()
Hope this helps, good luck!

Indirekter Function-Aufruf über einen Delegaten

Posted: Thu Feb 28, 2019 1:47 pm
by lumberjack
Robert,
robert wrote:Peter,
Or try this:
You beat me by a split second. Obviously I have tried to modify his code the VN way... Not sure if that still work?
Regards,

Indirekter Function-Aufruf über einen Delegaten

Posted: Thu Feb 28, 2019 1:57 pm
by FFF
Both of you need a
USING system.Collections.Generic at the top, then Robert's works, while Johan's version returns "funDel" instead :)

Indirekter Function-Aufruf über einen Delegaten

Posted: Thu Feb 28, 2019 3:15 pm
by robert
Johan,

In stead of

Code: Select all

f1Del := funDel{null, @f1()}

you can also use

Code: Select all

f1Del := f1
You were indeed using the VN syntax

Robert

Indirekter Function-Aufruf über einen Delegaten

Posted: Thu Feb 28, 2019 3:38 pm
by lumberjack
Hi Karl,
FFF wrote:Both of you need a
USING system.Collections.Generic at the top, then Robert's works, while Johan's version returns "funDel" instead :)
I will however need to install System.Collections.Languages.German additionally...

Indirekter Function-Aufruf über einen Delegaten

Posted: Thu Feb 28, 2019 9:04 pm
by pemo18
Thank you everyone.

This is the shortest (and still readable) version I came up with:

Code: Select all

USING System
USING System.Collections.Generic

BEGIN NAMESPACE IndirekterAufruf

Delegate funDel() As String
    
FUNCTION Start() AS VOID STRICT
        Local funDic := Dictionary<int, fundel>{} AS Dictionary<int, fundel>
        funDic:Add(1, { => "Cloudy day ahead" }  )
        funDic:Add(2, { => "Sunny the whole day" })
        funDic:Add(3, { => "Rain, rain and even more rain" })
        Local z := Random{}:@@Next(1,funDic:Count + 1) as int
        Console.WriteLine("The weather forecast for today: {0}", funDic[z]())
If XSharp is as close to C# as I assume I probably don't have to use a delegate.

I even found a translation class;)

Peter