Autor Beitrag
Cäptin Pommes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 142
Erhaltene Danke: 2



BeitragVerfasst: Mi 01.02.12 13:38 
hi leute,

ich lese gerade was zu dem oben genannten thema und ... tja, ich verstehs ganz einfach nicht.
Ich versteh nicht wozu man sowas braucht und überhaupt was es macht ... das is bisher das erste kapitel des Buches was ich wirklich absolut nich mal im ansatz verstehe ^^

könnt ihr mir da irgentwie helfen?
vieleicht mit nem sinvollen beispiel? - sowas fehlt dazu in meinem buch leider :/


danke im vorraus
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 01.02.12 14:18 
Brauchen hört sich so nach Notwendigkeit an. Es geht natürlich auch ohne. Sie sind aber ein Angebot um die Lesbarkeit (ich würde sogar von Ausdruckstärke sprechen) des Codes zu erhöhen.

Simples Beispiel : Zählen der ungeraden Zahlen in einer List mit dessen Count Methode.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
static class Program
{
    static void Main()
    {
        int[] numbers = { 5413986720 };

        // klassisch mit explizitem Methodenaufruf/Delegatenaufruf
        int CountOddNumbersViaMethode = numbers.Count(IsOdd);

        // mit anonymer Methode/Delagate
        int CountOddNumbersViaDelegate = numbers.Count(delegate(int n) { return n % 2 == 1; });
       
        // mit Lambdaausdruck
        int CountOddNumbersViaLambda = numbers.Count(n => n % 2 == 1);     
    }

    static bool IsOdd(int n)
    {
        return n % 2 == 1;
    }
}


Alle 3 Methoden liefern das gleiche Ergebnis da sie (wenn man sich den daraus generierten IL code ansehen würde ganz offensichtlich) das gleiche machen.
Sobald man Lambdas lesen/verstehen kann so wie jeden anderen Code auch kann man damit aber am lesbarsten und kompaktesten ausdrücken was ein Code anstellt ohne ausschweifende Kommentierung.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 01.02.12 14:27 
Hallo,

vllt. hilft dir folgender Artikel weiter: Delegaten, anonyme Methoden, Lambda-Ausdrücke & Co. ?

Ein Delegate ist einfach ein "Methodenzeiger" (bzw. Methodenreferenz). Wenn du eine allgemeine Methode schreibst, welche intern eine beliebige andere Methode aufrufen soll, dann übergibst du diese Methode als Delegate.

Ein übliches Beispiel dafür wäre die Accumulate-Methode:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
delegate int Operation(int a, int b);

int Accumulate(IList<int> list, Operation operation, int startValue)
{
  int y = startValue;

  foreach (int x in list)
    y = operation(y, x);

  return y;
}

So kannst du diese Methode mit verschiedenen Operationen aufrufen, z.B.
ausblenden C#-Quelltext
1:
2:
3:
4:
List<int> numbers = { 12345 };

int sum = Accumulate(numbers, Add, 0);
int product = Accumulate(numbers, Mul, 1);

wobei die Methoden Add und Mul einfach so definiert sind:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
int Add(int a, int b)
{
  return a + b;
}

int Mul(int a, int b)
{
  return a * b;
}


Und anonyme Methoden bzw. Lambda-Ausdrücke sind nur eine verkürzte (Inline-)Schreibweise für diese Methoden:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
// anonyme Methode
int sum = Accumulate(numbers, delegate (int a, int b) { return a + b; }, 0);

// Lambda-Ausdruck
int product = Accumulate(numbers, (a, b) => { a * b }, 1);


Ich benutze diesen Ansatz auch in meinem Parser für mathematische Formeln, damit beliebige Operationen definiert werden können.
Cäptin Pommes Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 142
Erhaltene Danke: 2



BeitragVerfasst: Fr 03.02.12 13:22 
puh ... also ich hab mir den artikel mal durchgelesen ...
also wenn ich das richtig verstanden habe dann erstelle ich mit delegate im prinzip nen typ der eine methode nimmt die die entsprechenden parameter und rückgabe wert haben

davon erstelle ich mir praktisch ein objekt und weise ihm eine passende methode zu, dann kann ich das objekt wie die eigentliche methode benutzen

hab ich das so richtig verstanden?
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 03.02.12 14:14 
Hallo,

ja (so in etwa ;-))

Weitere Beispiel für Einsatz von Delegaten sind z.B. innerhalb der Sort-Methode, um seine eigene Sortiermethode zu übergeben oder bei der Array.Find<T>-Methode, um das individuelle Suchkriterium anzugeben.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 03.02.12 14:57 
Da du am Anfang die Frage gestellt hast wofür man das braucht wollen wir auch den häufigste Anwendungsfall nicht verschweigen. Jeder Event ist natürlich auch ein delegate.
Cäptin Pommes Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 142
Erhaltene Danke: 2



BeitragVerfasst: Fr 03.02.12 15:12 
ok, nun weiss ich in etwa wie das funktioniert ... aber erhlich gesagt macht es für mich dadurch nich mehr sinn ... wieso weise ich nen delegate eine methode zu die ich dann über den delagte benutze anstatt die methode direkt zu benutzen?
ujr
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 102
Erhaltene Danke: 12



BeitragVerfasst: Fr 03.02.12 15:20 
user profile iconCäptin Pommes hat folgendes geschrieben Zum zitierten Posting springen:
ok, nun weiss ich in etwa wie das funktioniert ... aber erhlich gesagt macht es für mich dadurch nich mehr sinn ... wieso weise ich nen delegate eine methode zu die ich dann über den delagte benutze anstatt die methode direkt zu benutzen?


Welche Methode denn? U.a. bei Events siehst Du doch, dass die eigentliche Methode zur Entwurfs/Compilezeit nicht bekannt ist.
Oder Du kannst die eigentliche Implementierung zur Laufzeit ändern: sortiere nach Namen, nach Datum, ... und trotzdem den selben Code benutzen (für den Sort Aufruf).
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 03.02.12 16:15 
Stell dir den Delegaten als Platzhalter für eine noch zu bestimmende Methode vor. Der Delegat bestimmt nur die Signatur welche die Methode aufweisen muß aber nicht welche Methode benutzt wird.

Vielleicht hilft es dir wenn du dir überlegst wir die von user profile iconTh69 verlinkte Sort Methode ohne Delegate aussehen würde. Also du hast ein Liste die zum Sortieren vorbereitet ist das konkrete Verfahren wie zwei Elemente in der Liste verglichen werden um sie zu sortieren aber von einer anderen Klasse implementiert werden soll. Wie würdest du das machen wenn es in C# keine Delegaten gäbe? Vermutlich kommst du nur auf Lösungen die komplexer und/oder komplizierter als ein Delegat sind oder einem Delegaten äquivalent wären.
Cäptin Pommes Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 142
Erhaltene Danke: 2



BeitragVerfasst: Fr 03.02.12 16:44 
hmm ich merk grad ich versteh das beispiel nich mal ... wo bekommt der denn die Parameter x und y her wenn er Sort() aufruft?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 04.02.12 01:44 
Zitat:
wo bekommt der denn die Parameter x und y her wenn er Sort() aufruf


Die kommen aus der Liste. Die Liste kann sortieren hat nur das Problem denn dabei notwendigen Vergleich zwischen 2 Elementen auszuführen. Der Sortieralgorithmus in der Liste wird regelmäßig vergleichen müssen. Dazu ruft es dann jedesmal den Delegaten auf und übergibt die 2 zu vergleichenden Elemente. Die heißen dann hier jetzt halt mal x und y. Die Methode hinter dem Delegaten führt dann den Vergleich aus gibt ein Ergebnis zurück und die Liste kann damit das Sortieren fortsetzen.