Methoden (fortgeschritten) in C# - 1 Marc Satkowski 20. November 2016 C# Kurs
Gliederung 1. Opertatoren Überladung 2. delegate 3. Anonyme Methoden delegate Lamda Ausdruck-Lamdas Anweisung-Lamdas Variablenbereich für Lamdas 1
Opertatoren Überladung
Opertatoren Überladung Operatoren unäre +, -,!, ~, ++, --, true, false binär +, -, *, /, %, &,, ^, <<, >> vergleich ==,!=, <, >, <=, >= Andere Operatoren können nicht überschrieben werden Operatoren wie += und && werden durch + und & beschrieben true und false geben dem Objekt die Möglichkeit wie bool behandelt zu werden Bei Vergleichsoperatoren muss der jeweilige Gegensatz auch überschrieben werden (z.b. bei == auch!= überschreiben) 2
Opertatoren Überladung Alle Typen können statische Methoden haben, welche Operatoren überschreiben und neu definieren können Syntax: public static <Datentyp> operator <Operator> ( [Übergabeparameter] ) { <Code> } Verschiedene Operatoren brauchen verschiedene Übergabeparameter und Rückgabeparameter Man kann den selben Operator mit verschiedenen Übergabetypen überladen 3
Opertatoren Überladung 1 public class EineKlasse 2 { 3 public List <int > elements ; 4 public EineKlasse ( int anzahl ) 5 { elements = new List <int >( anzahl ); } 6 // Eine Ueberladung fuer + und true. 7 public static EineKlasse operator +( EineKlasse a, EineKlasse b) 8 { return new EineKlasse ( a. elements. Count + b. elements. Count ); } 9 public static bool operator true ( EineKlasse obj ) 10 { return elements. Count > 0? true : false ; } 11 } 1 EineKlasse obj1 = new EineKlasse (); 2 EineKlasse obj2 = new EineKlasse (); 3 // Benutzung der Addition. 4 EineKlasse summe = obj1 + obj2 ; 5 // Vergleich mit der Summe. 6 if( summe ) 7 { /* Code */ } 4
delegate
delegate Auch Funktionspointer genannt Schlüsselwort zur Kapselung der Signatur von Methoden, um Referenzen auf diese abbilden zu können Es wird für diese (wie bei den Methoden) Übergabeparameter und Rückgabetyp deklariert Alle Methoden mit dieser Signatur können durch den Delegate dargestellt werden Wird genutzt um eine Methode aufzurufen ohne auf dessen Objekt eine Referenz zuhaben Syntax (zur Datentyp Deklarierung): delegate <Rückgabetyp> <Delegatename> ( [Übergabeparameter] ); Syntax (zur Variablen Deklaration und Instanziierung): <Delegantename> <Variablenname> = <Methodenname>; Variable wird genauso genutzt wie eine normale Methode 5
delegate 1 // Ein Delegate - Typ erstellt. 2 public delegate int EinDelegate ( int param ); 3 4 public class EineKlasse 5 { 6 public int EineMethode ( int einparam ) 7 { 8 return 42 + einparam ; 9 } 10 } 1 EineKlasse obj = new EineKlasse (); 2 // Delegate - Variable erstellen und befuellen. 3 EinDelegate variable = obj. EineMethode ; 4 // Aufruf des Delegates. 5 int erg = variable (24) ; 6 if( erg == 76) 7 { /* Code */ } 6
Anonyme Methoden
Anonyme Methoden Haben keinen eigenen Methodenkopf Können nur durch Delegate-Variablen aufgerufen und genutzt werden Es gibt 2 Arten der Erstellung: Durch Schlüsselwort delegate Über Lamda-Terme 7
delegate delegate kann auch als Methodendefinition genutzt werden Syntax: <Delegate-Variable> = delegate( [Übergabeparameter] ) { <Code> }; 1 // Ein Delegate - Typ erstellt. 2 public delegate int EinDelegate ( int param ); 1 EinDelegate variable = delegate ( int a) 2 { 3 // Code 4 }; 8
Lamda Benutzt den Lamda-Operator => Syntax: ( [Übergabeparameter] ) => { <Code> }; Es gibt Unterschiede in der Syntax zwischen den einzelnen Lamda Arten Übergabeparameter brauchen nicht immer einen Typ, da dieser hergeleitet werden kann 9
Ausdruck-Lamdas Besitzt im Körper nur einen Ausdruck und braucht somit keine geschweiften Klammern Gibt als Ergebnis das Ergebnis des einen Ausdrucks zurück 1 // Mehrere Delegate - Typen erstellt. 2 public delegate string LeerDelegate (); 3 public delegate bool EinDelegate ( float param ); 4 public delegate float ZweiDelegate ( int a, int b); 1 // Methoden ohne Parameter brauchen () 2 LeerDelegate var0 = () => " Hallo "; 3 string s = var0 () + " Welt!"; 4 // Ein Parameter braucht keine () ausser, wenn der Typ 5 // mit angegeben wird 6 EinDelegate var1 = ( float val ) => val < 100; 7 bool b = var1 (20.0 f) 8 // Zwei Parameter brauchen () 9 ZweiDelegate var2 = ( int1, int2 ) => int1 - int2 ; 10 int z = var2 (76, 24) ; 10
Anweisung-Lamdas Besitzen zur Eingrenzung des Körpers geschweifte Klammern Müssen nun (wenn kein void als Rückgabetyp) ein return besitzen 1 // Mehrere Delegate - Typen erstellt. 2 public delegate void LeerDelegate (); 3 public delegate float EinDelegate ( float param ); 1 // Methoden ohne Parameter brauchen () 2 LeerDelegate var0 = () => 3 { 4 string s = " Hallo World "; 5 Console. WriteLine (s); 6 }; 7 var0 (); 8 // Ein Parameter braucht keine () ausser, wenn der Typ 9 // mit angegeben wird 10 EinDelegate var1 = x => { x *= x; x *= x; return x; }; 11 float z = var1 (2) ; 11
Variablenbereich für Lamdas Lamdas können auf Variablen außerhalb ihres eigenen Gültigkeitsbereichs/Scopes verweisen und diese nutzen Diese werden zur Verwendung im Lamda gespeichert In diesem Fall werden lokale Referenzen zu den Objekten im Lamda gespeichert Solch eine äußere Variable muss definitiv vorher zugewiesen sein 1 // Mehrere Delegate - Typen erstellt. 2 public delegate void LeerDelegate (); 3 public delegate float EinDelegate ( float param ); 12
Variablenbereich für Lamdas 1 LeerDelegate var0 ; 2 EinDelegate var1 ; 3 4 // Alle Variablen in dieser Methode koennen in Lamdas 5 // genutzt werden. 6 private void EineMethode ( int zahl ) 7 { 8 // Muss vorher einen Wert haben. 9 int val = 7; 10 var0 += () => Console. WriteLine ( zahl + "-" + val ); 11 var1 += ( float x) => 12 { 13 // Kann ueberschrieben werden. 14 val *= x; 15 val -= zahl ; 16 return val ; 17 }; 18 } 13