Jazyk C# (seminář 6) Pavel Procházka KMI 29. října 2014
Delegát motivace Delegáty a události Jak docílit v C# funkcionální práce s metodami v C je to pomocí pointerů na funkce. Proč to v C# nejde pomocí pointerů na funkce která vlastnost jazyka by se tím zbořila? Přitom takovou funkcionalitu ale nutně potřebujeme kvůli GUI callbackům neboli událostem Události ve smyslu GUI knihoven jsou reakce na vstupy uživatele (například kliknutí, stistknutí klávesy) Knihovny jsou obvykle asynchronní a běh vykreslování si řídí samy (v hlavní smyčce) je proto nutné deklarovat reakce dopředu při vytvoření grafického objektu
Delegáty řešení pomocí interface První možnost je obalením každé funkce pomocí předdefinovaným interfacem Docela zdlouhavé (Java style) interface IMyCallableFunc void SampleCall(); class MyCallable : IMyCallableFunc public void SampleCall() Console.WriteLine( "Hello World!" );... MyCallable c = new MyCallable(); for( int x = 0 ; x < 10 ; x++ ) c.samplecall();
Delegáty řešení od Microsoftu Nové klíčové slovo delegate Postup 1. deklarace delegátu pomocí klíčového slova delegate, 2. Vytvoření objektu tohoto typu (pomocí new) a inicializace pomocí nějaké metody, 3. zavolání pomocí () delegate void MyDelegate( int i ); class MainClass public static void MyFunc( int i ) Console.WriteLine( "Hello World 0", i ); public static void Main (string[] args) MyDelegate md = new MyDelegate( MyFunc ); for (int i = 0; i < 10; i++) md (i);
Indexery Další způsob, jak umožnit, aby se objekt choval jako pole šel indexovat pomocí [] Už známe způsob pomocí iterátorů (týká se foreach) a pomocí přetížení operátoru [] Existuje způsob pomocí indexeru, což je speciální nová syntaxe, podobná get, set public class Stack private Node GetNode(int index)... public object this[int index] get return GetNode(index).Value; set GetNode(index).Value = value;... s[0] = 33 Console.WriteLine( "0", s[0] ); // => 33
Finalizery Využití se nachází v případě, když chceme něco provést při uvolnění objektu garbage collectorem Tzn. jedná se o opak ke konstruktoru ten objekt zakládá řízeným způsobem, finalizer ho řízeně ruší Typické použití, pokud používáme nativní knihovnu, která je napsána například v C a potřebujeme, nějak sdělit knihovně, že jí zabraný prostředek je potřeba uvolnit Využití také v GUI Syntaxe je podobná jako u konstruktoru je to metoda, která se jmenuje jako třída a má prefix, nesmí brát žádný argument (protože je volaná garbage collectorem), nesmí být explicitně volána uživatelem ClassName() /* implementation*/
Finalizer demo Delegáty a události class Point public double x, y; public Point(double x, double y) this.x = x; this.y = y; Point() Console.WriteLine("Finalized 0", this); public override string ToString() return string.format("(0, 1)", x, y);
Statické členské proměnné a metod Pomocí klíčového slova static můžeme deklarovat členské proměnné a metody, aniž by existovala instance objektu dané třídy (jedná se tedy vpodstatě o globální proměnné a funkce) public class Automobile public static int NumberOfWheels = 4; public static int SizeOfGasTank get return 15; public static void Drive() Automobile.Drive(); int i = Automobile.NumberOfWheels;
Anonymní metody Delegáty a události Podobné funkcionálnímu lambda z jazyka scheme Problém se statickým typováním, je potřeba vždy dopředu říci, jak ten callback bude vypadat... delegate bool Action(Node n); static void Walk(Node n, Action a) while (n!= null && a(n)) n = n.next;... Walk(list, delegate(node n) Console.WriteLine(n.Name); return true; );
Klíčové slovo var Delegáty a události Pokud se nechceme vypisovat s potenciálně dlouhým typem proměnné nebo si nepamatujeme přesné znění, můžeme použít klíčové slovo var Typické použití ve foreach string[] words = "apple", "strawberry", "grape", "peach", "banana" ; foreach (var s in words) Console.WriteLine(s);
Klíčové slovo const Delegáty a události Klíčové slovo const slouží k deklaraci konstanty Používá se na (členské) proměnné Nelze za běhu měnit, je totiž odvozena už při kompilaci a neleží na žádné adrese public const int c1 = 5; public const int c2 = c1 + 5;... Console.WriteLine( c2 ); // => 10
A ted vy Napište funcionální třídu Cons, která se chová jako cons ve scheme Vytvořte seznam List, který využívá třídy Cons, stejně jak je tomu ve Scheme Implementujte metodu Map, která se chová stejně jako map Implementujte metodu Filter, která se chová stejně jako map Nakonec můžete implementovat Foldr, Foldl,...