Entwickler-Ecke
C# - Die Sprache - Delegate und Lambda Ausdruck
kostonstyle - Di 16.02.10 11:32
Titel: Delegate und Lambda Ausdruck
hallo miteinander
habe wiedermal eine Frage, und zwar geht es um dieser Codeausschnitt
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| AsyncCallback callback = new AsyncCallback(ar => { long primeNumber = primeNumberDelegate.EndInvoke(ar);
this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { this.lblInfo.Content = primeNumber.ToString(); this.btnCalculatePrimeNumber.IsEnabled = true; })); }); |
Hier wird ein Instanz von der Delegate AsyncCallback erzeugt.
Die Definition von den Delegate
C#-Quelltext
1:
| public delegate void AsyncCallback(IAsyncResult ar); |
Was ich nicht gewusst habe ist, dass man ein Delegate instanzieren kann. Das Argument ar, warum kann man hier ein Lambda Ausdruck zuweisen, obwohl der Typ definiert ist(IAsyncResult). IAsyncResult ist ein Interface, muss man nicht hier die Methode implementieren.
Da ich ein Anfänger bin, kenne ich nur einfache Bespiele für den Einsatz von Delegaten. Aber hier, ist so kompliziert.....
Gruss kostonstyle
Kha - Di 16.02.10 19:55
kostonstyle hat folgendes geschrieben : |
Was ich nicht gewusst habe ist, dass man ein Delegate instanzieren kann. |
Kann man bzw. muss man, denn Delegates sind auch "nur" Objekte. Mit dem Instanzieren hast du aber etwas falsch verstanden, dort übergibst du nicht die Argumente des Delegates. Was sollte bei so einem Code auch passieren?
C#-Quelltext
1: 2:
| IAsyncResult ar = ...; AsyncCallback ac = new AsyncCallback(ar); |
Ein Delegate ist schließlich ein Methodenzeiger, also musst du dem Konstruktor eine Methode übergeben:
C#-Quelltext
1: 2: 3: 4: 5:
| void MyCallback(IAsyncResult ar) { ... }
AsyncCallback ac = new AsyncCallback(MyCallback); |
Der Code mit Lambda-Ausdruck (oder anonymer Methode) ist dazu exakt äquivalent:
C#-Quelltext
1:
| AsyncCallback ac = new AsyncCallback(ar => ...); |
In diesem Sinne ist der Code auch etwas merkwürdig (woher stammt der?), man würde normalerweise genauso wie bei MyCallback einfach
C#-Quelltext
1: 2: 3:
| AsyncCallback ac = ar => { ... }; |
schreiben. Explizite
news auf Delegate-Typen braucht man seit 2.0 eigentlich überhaupt nicht mehr.
kostonstyle - Mi 17.02.10 11:04
das Beispiel habe ich aus dem Buch Visual C#. Dieser Codeausschnitt von dir macht die Definition von Delegate Methode deutlicher für ein Anfänger
C#-Quelltext
1: 2: 3: 4: 5:
| void MyCallback(IAsyncResult ar) { ... }
AsyncCallback ac = new AsyncCallback(MyCallback); |
in dieser Methode kann man dann den Instanz ar von Type IAsyncResult nutzen. Zum Beispiel
C#-Quelltext
1: 2: 3: 4:
| void MyCallback(IAsyncResult ar) { bool complete = ar.IsCompleted; } |
So weit so klar.
Aber wenn so mit Lambda Ausdruck geschrieben wird
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| AsyncCallback callback = new AsyncCallback(ar => { long primeNumber = primeNumberDelegate.EndInvoke(ar);
this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { this.lblInfo.Content = primeNumber.ToString(); this.btnCalculatePrimeNumber.IsEnabled = true; })); }); |
ist für einen Anfänger so schwierig zu nachvollziehen. Wie kann ich hier das Argument ar in diesem Codeblock nutzen?
Das Beispiel findet ihr im Anhang.
Danke kostonstyle
Kha - Mi 17.02.10 20:32
kostonstyle hat folgendes geschrieben : |
Wie kann ich hier das Argument ar in diesem Codeblock nutzen? |
Noch einmal: Wichtig ist, dass Folgendes exakt äquivalent ist.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7:
| void MyCallback(AsyncResult ar) { long primeNumber = primeNumberDelegate.EndInvoke(ar); ... };
primeNumberDelegate.BeginInvoke(startNumber, MyCallback, null); |
C#-Quelltext
1: 2: 3: 4: 5: 6:
| primeNumberDelegate.BeginInvoke(startNumber, ar => { long primeNumber = primeNumberDelegate.EndInvoke(ar); ... }, null); |
PS: In den meisten Fällen (und spätestens ab 4.0 mit der Task Parallel Library) sind Asynchronous Delegates nicht wirklich hilfreich. Hier würde ich eher so etwas verwenden:
C#-Quelltext
1: 2: 3: 4:
| ThreadPool.QueueUserWorkItem(state => { long primeNumber = NextPrimeNumber(startNumber); Dispatcher.BeginInvoke(...); }); |
kostonstyle - Do 18.02.10 08:27
entschuldige, was ich immer noch nicht verstehe, ist das man das Argument ar ein Lambda Ausdruck zuweisen kann, dass ist so unlogisch, zu mindest für ein Anfänger wie ich.
Christian S. - Do 18.02.10 16:41
"=>" ist keine Zwuweisung!
ar => { ... } ist der komplette Lambda-Ausdruck, also inklusive des "ar =>". Links vom "=>" stehen die Parameter (also was bei einer "normalen" Methode in der Klammer käme) und rechts vom "=>" steht, was mit den Parametern gemacht wird.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!