Język C# ( 5.0 ) using System; namespace HeWo { class Hello using System; namespace HeWo { class Hello static void Main(string [] args) Console.WriteLine("Hello World!"); }
Typy Danych wartości ( stos , pełne kopiowanie ) logiczne numeryczne egzemplarze struktur referencje ( sterta , kopiowanie referencji ) obiekty klas tablice ciągi znaków ( string )
Type C# CTS CLS Bytes Default bool Boolean Y 1 false byte Byte Y 1 0 sbyte SByte N 1 0 short Int16 Y 2 0 int Int32 Y 4 0 long Int64 Y 8 0 ushort UInt16 N 2 0 uint UInt32 N 4 0 ulong UInt64 N 8 0 float Single Y 4 0.0 double Double Y 8 0.0 char Char Y 2 0 decimal Decimal Y 16 0.0
Deklaracje i definicje zmiennych Operator przypisania wartości int Alfa , Beta , Gamma = 5 ; Operator przypisania wartości Beta = Gamma; // OK Beta = 12; // OK Beta = Alfa; // błąd kompilacji Stałe const double Kurs = 3.857 ;
Typy implikowane (3.0) var a = 5; // int var b = 'K'; // char var c = 128L; // long var d = 15.332; // double var e = "Ala ma kota"; // string a = 4654434L; // long -> int e = 4.5; // błąd ● tylko zmienne lokalne w funkcjach - nie mogą być składowymi klas
Rzutowanie · automatyczne - rozszerzające ( bez ostrzeżenia ) - zawężające ( błąd kompilacji ) · wymuszone (int) LongValue; int li32 = 5; long li64; li64 = li32; // OK. li32 = li64; // błąd kompilacji li64 = 100111222333; li32 = (int) li64; // błędna wartość // 1236974525
Typy rozszerzone ( nullable ) (2.0) double? Cena; // { numbs, INF, NaN, null } // Cena = 7.54 ; Cena = null ; if ( Cena.HasValue ) Cena += 1.4;
· operator ?? int Parametr; int? Pomiar = null; /* . . . . . . . . */ Parametr = Pomiar ?? 100 ; // 100 gdy null // string str = null; Console.WriteLine( str ?? "Pusty" ); // Pusty gdy null
Opakowanie – Rozpakowanie long aaa = 1234567890 , bbb ; object objLong = aaa ; // stos sterta bbb = (long) objLong ; // sterta stos // InvalidCastException
Typ logiczny bool dobrze; int alfa = 5; dobrze = 0; // błąd dobrze = 3 * alfa + 1; // błąd dobrze = true; // OK dobrze = alfa > 10; // OK
Typy wyliczeniowe enum Wyliczanka // int { Eme, // == 0 Due, // == 1 Fake = 10, // == 10 Drake // == 11 } enum Maly : byte // byte { mini , mikro } · dziedziczenie z System.Enum Enum.IsDefined(typeof(Maly) , "nano");
Funkcje i właściwości typów · zmienne typów będących wartościami są egzemplarzami struktur dziedziczą funkcje z typu System.Object.ValueType ─ GetType( ) // obiekt Type określający typ dla typów wyliczeniowych (np. ConsoleColor) : var ListaKolorów = // tablica stałych Enum.GetValues(ConsoleColor.Black.GetType()); ─ ToString( ) // konwersja binarno – znakowa long LoVal = 15342443 ; string Characters = LoVal.ToString ( );
· właściwości typów liczbowych MaxValue // wartość maksymalna MinValue // wartość minimalna long x = long.MaxValue; int y = int.MinValue;
Łańcuchy znaków UNICODE (UTF - 16) · string typ referencyjny · zawartość łańcucha niezmienna · dziedziczy z typu System.String Length, Concat, CompareTo, Copy, Insert , PadLeft , PadRight , Remove , Replace , ToLower , ToUpper , Format = , + , == , != , [ ] string Nap1 , Nap2 = "dobry napis" ; Nap1 = Nap2 ; // nowa referencja Nap1 = Nap2.ToUpper( ); // nowy łańcuch
Przekształcanie wnętrza łańcucha · znaki sterujące jak w C ( @ wyłącza przetwarzanie ) string Opis1 = "\nWyniki\t:" ; string Opis2 = @"\nBez zmian\t:" ; Przekształcanie wnętrza łańcucha · klasa System.Text.StringBuilder using namespace System.Text; StringBuilder myBuffer = new StringBuilder ("Ala ma kota"); myBuffer.Append(„ a Ola psa."); myBuffer.Insert(11, ','); string Ready = myBuffer.ToString(); // Ala ma kota, a Ola psa.
Wprowadzanie – wyprowadzanie danych · klasa System.Console ─ int Read ( ) // 1 znak (NL, -1) ─ string ReadLine ( ) // do NL ─ string Write ( string ) // bez NL ─ string WriteLine ( string ) // z NL // Console.WriteLine( x.ToString() ); Console.WriteLine( x ); // konwersja Console.WriteLine( x.ToString() + ", " + y.ToString() );
Console.Write ("format", w,..,w) // bez NL Console.WriteLine ("format", w,..,w) // z NL format "zzz{0}zzz{1}zzz{0}zzz{2}zzz..." ─ "zzz" dowolny ciąg znaków (może być pusty) ─ {0} {1} {2} ... pozycje kolejnych dalszych argumentów ─ w,...,w ciąg wyrażeń
niecałkowite dziesiętne postać heksydecymalna · można stosować znaki formatujące {K:Zs} lub {K,P:Zs} ─ K numer pozycji ─ Z znak formatujący ─ P szerokość pola ─ s liczba cyfr po kropce znak znaczenie C c waluta (wg. Windows) D d całkowite dziesiętne E e notacja wykładnicza F f niecałkowite dziesiętne z wykładnikiem lub bez G g N n format narodowy X x postać heksydecymalna
string str = "\nOpis wyniku :\t" ; Console.WriteLine( int ii = 34; double dd = 2.52345324 ; string str = "\nOpis wyniku :\t" ; Console.WriteLine( "{0} {1} albo {1,12:D} i {2} lub\n " + "{2,-15:F3} lub {2:E5} lub {3} " , str , ii , dd , dd.ToString() ) ; //Opis wyniku : 34 albo 34 i 2,52345324 lub // 2,523 lub 2,52345E+000 lub 2,52345324
· konwersja znakowo – binarna (kultura - ustawienia narodowe) - SystemType.Parse(string) string str; double dd = 2.5; str = Console.ReadLine( ); // 12,45 dd = double.Parse( str ); // błędny format -> błąd wykonania Console.WriteLine( dd ); // 12,45
bool dobrze = false; string str; double dd = 2.5; while ( ! dobrze ) { str = Console.ReadLine( ); dobrze = double.TryParse(str, out dd); } Console.WriteLine(dd); // VS.NET 2005
- klasa Convert ToByte ToSByte ToChar ToDecimal ToDouble ToSingle ToInt16 ToInt32 ToInt64 ToUInt16 ToUInt32 ToUInt64 ToString string st; long war; str = Console.ReadLine(); // 124534567043 war = Convert.ToInt64(str); // format Console.WriteLine(war); // 124534567043
· kultura (ustawienia narodowe) - związana z każdym procesem obliczeniowym (wątkiem) - klasa CultureInfo using System.Threading; using System.Globalization; // CultureInfo ci = new CultureInfo("de-DE"); Thread.CurrentThread.CurrentCulture = ci;
· przesuwanie kursora // VS.2005 Console.CursorVisible = false; Console.ForegroundColor = ConsoleColor.Red; Console.BackgroundColor = ConsoleColor.White; Console.CursorLeft = X; // od lewej Console.CursorTop = Y; // od góry Console.SetCursorPosition( X, Y ); Console.Write("+"); // o 1 w prawo Console.CursorLeft = X; // powrót Console.Clear();
· znaki sterujące ConsoleKeyInfo znak; // znak = Console.ReadKey(); if( ConsoleKey.UpArrow == znak.Key) { .... } // Backspace, Home, End, Enter, Escape // Arrows, Fxx, klawiatura numeryczna // Play, Volume, ... Console.Beep( 3000, 1000 ); // 3000 Hz, 1000 ms Call, S0, Kultura,Move
Wyrażenia arytmetyczne i logiczne · operatory i zasady tworzenia jak w C++ · dodatkowo is as oraz => · konwersja wartości - rozszerzająca automatycznie - zawężająca błąd int a = 2L; // błąd float f = 2.45; // błąd · rzutowanie ( typ ) wyrażenie
· lokalne testowanie poprawności checked // typy całkowitoliczbowe int a1 = 2000000000; a1 = a1 + 2000000000; // -294967296 a1 = checked ( a1 + 2000000000 ); // wyjątek long l1 = 5000000000; a1 = l1; // błąd kompilacji a1 = ( int ) l1; // -294967296 a1 = checked ( ( int ) l1 ); // wyjątek
· globalne testowanie poprawności Properites / Build / Advance Check for arithmetic overflow/underflow · lokalne wyłącznie testowania unchecked int a1 = 2000000000; a1 = a1 + 2000000000; // wyjątek a1 = unchecked ( a1 + 2000000000 ); -294967296 +
Instrukcje · warunkowe if .. else // jak C++ // warunek wyrażenie logiczne if ((x + 4) > 1 && (y++ < 8)) // || // obliczenie optymalizowane if ((x + 4) > 1 & (y++ < 8)) // | // pełne obliczenie // switch // jak C++ // instrukcja break konieczna
· pętle ( ogólnie jak C++ ) for ( int i = 1 ; i < 5 && dalej ; ++i ) { ....... } // koniec widoczności zmiennej i while , do ... while // jak C++ foreach // wymagany IEnumerator
Struktury · są zawsze wartościami (na stosie, kopiowanie) · mogą zawierać interfejsy, funkcje składowe i konstruktory z argumentami · są zawsze zapieczętowane · modyfikatory dostępu do pól modyfikator opis public dostępne zewsząd (domyślny) private tylko wewnątrz struktury / klasy protected dla klas dziedziczących internal tylko w pakiecie protected internal dla klas dziedziczących w pakiecie
public struct Osoba { public string Imie; public string Nazwisko; public long Pesel; } Osoba Prezes; Prezes.Imie = "Adam" ; Prezes.Nazwisko = "Betoński" ; Prezes.Pesel = 54031203287; Osoba Emeryt ; Emeryt = Prezes ;
· pakowanie i rozpakowanie object Agent = Emeryt; // sterta, brak dostępu do pól long kto = Agent.Pesel; // błąd Osoba X_007 = ( Osoba ) Agent ; // stos, jest dostęp do pól kto = X_007.Pesel; // OK
public struct Komputer { public string Marka; public short Cena; public Komputer (string mm, short cc) { Marka = mm; Cena = cc; } object PC = new Komputer ( "Alfa", 3000 ); short cc = PC.Cena; // błąd Komputer komp = (Komputer) PC; cc = komp.Cena; // OK
Tablice · jednowymiarowe int [ ] Tab_A ; // zmienna referencyjna Tab_A = new int [ 120 ] ; // 0 ... 119 // automatyczne zerowanie string [ ] Tab_B = new string [ X + 5 ] ; // automatycznie NULL
string [ ] Tab_D = new string [ 3 ] { "Alfa", "Beta", "Gamma" }; double [ ] Tab_C = { 1.2 , 4.5 , 4.4 } ; // Tab_A [ 0 ] = 55 ; Tab_D [ 2 ] = "Jota" ; // System.IndexOutOfRangeException var T = new double[ ]{1.1, 2.2, 3.3}; // tylko jako tablica lokalna w funkcji
· wielowymiarowe, pełne int [ , ] Mat = new int [ 9 , 7 ] ; Mat [ 3 , 5 ] = 121 ; // int [ , ] T23 = { {1, 2, 3}, {4, 5, 6} } ; var T2 = new long [ , ] { { 10, 20, 30 }, { 100, 200, 300 } }; // tylko jako tablica lokalna w funkcji
● wielowymiarowe, niepełne long [ ] [ ] Arr = new long [ 5 ] [ ] ; // zadana liczba wierszy, // zmienna liczba kolumn w wierszu for ( int i = 0 ; i < Arr.Length ; ++i ) Arr [ i ] = new long [ i + 5 ] ; Arr [ 2 ] [ 3 ] = 12212212234543 ;
· kopiowanie tablic int[] T = { 1, 3, 5, 7, 9 }; int[] R = new int [10]; R = T; // kopiowanie referencji, R ma 5 elementów T[0] = 99; // zmiana wartości R[0] R = (int[]) T.Clone(); // kopia T T[1] = 88; // R[1] bez zmian int[] S = new int [10]; T.CopyTo( S, 2 ); // kopiowanie elementów T -> S od elementu 2
· dziedziczenie z System.Array właściwości Length Range : [ ] 0 ; [ , ] wie : 0, kol : 1 [ , , ] ma : 0, wie : 1, kol : 2 funkcje BinarySearch , Clear , Clone, CopyTo GetLength, GetLowerBound , GetUpperBound GetValue , SetValue , Reverse , Sort
int x = 0; Array A3D = Array.CreateInstance(x.GetType(),12,15,24); // Range = 0, 1, 2 : M, W, K for (int i = A3D.GetLowerBound(0); i <= A3D.GetUpperBound(0); ++i) // M for (int j = A3D.GetLowerBound(1); j <= A3D.GetUpperBound(1); ++j) // W for (int k = A3D.GetLowerBound(2); k <= A3D.GetUpperBound(2); ++k) // K A3D.SetValue((i * 100 + j * 10 + k),i,j,k);
Console.WriteLine("Multidimensional Array:"); Console.WriteLine("Rank\tLower\tUpper"); for (int i = 0; i < A3D.Rank; ++i) Console.WriteLine("{0}\t{1}\t{2}", i, A3D.GetLowerBound(i), A3D.GetUpperBound(i)); Multidimensional Array: Rank Lower Upper 0 0 11 1 0 14 2 0 23
string [ ] Napisy = new string [ 10 ]; /* . . . . . . . . . . . */ foreach ( string s in Napisy ) { Console.Writeline( s ); } // interfejs IEnumerator jest dostępny S1, MatMul, Taba, Ewide
Funkcje · tylko funkcje składowe klas · niepotrzebne deklaracje ( zapowiedzi ) · modyfikatory argumentów modyfikator opis ( brak ) przez wartość ( kopiowanie ) , argument aktualny musi być zainicjowany out przez referencję, argument aktualny może być niezainicjowany ref przez referencję, argument aktualny musi być zainicjowany params zmienna liczba parametrów
public long F ( long p1 , out int p2 , ref double p3 ) { ... = ... p1 ... p3 ... ; ........... p2 = ....... ; p3 = ....p1 ... p2 ... ; return .... ; }
long wynik , a1 = 229977446633 ; int rezultat ; double zmiana = 21.4E5 ; wynik = F (a1 + 1L, out rezultat , ref zmiana); /* nawet gdyby zmienna rezultat miała nadaną wartość przed wywołaniem F, to i tak w funkcji F nie wolno odczytywać tej wartości przed wewnętrznym ustaleniem wartości p2 */ EwideF
· dowolna liczba parametrów – params public void DoLi (ref int Suma, params int [ ] Liczby) { foreach (int li in Liczby) Suma += li; } // int Wynik = 174; DoLi ( ref Wynik, 3, 5, 22, -7, 12); // 209
· wzorce funkcji ( generics ) public void PoLi <TyDa>(params TyDa [ ] Liczby) { foreach (TyDa li in Liczby) Console.WriteLine(li.ToString()); // Suma + li; niepoprawne // jedynie przypisanie = } // PoLi <double> (231.43, 99.89, - 15.2321);
public T Mała < T > (T p1, T p2) where T : System public T Mała < T > (T p1, T p2) where T : System.IComparable< T > { T pom; if ( p1.CompareTo( p2 ) < 0 ) pom = p1; else pom = p2; return pom; } double x; x = Mała <double> (231.43, 99.89);
· wartości domyślne i argumenty nazwane ( 4.0 ) public long FU ( long p1 , bool p2 = true , double p3 = 2.7 ) { ... } // long lili; lili = FU ( 127 ); // poprawnie lili = FU ( 127, false ); // poprawnie lili = FU ( 127, false, 3.9 ); // poprawnie lili = FU ( 127, , 3.9 ); // błąd lili = FU ( 127, 3.9 ); // błąd lili = FU ( 127, p3 : 3.9 ) // poprawnie NamedPar, Refa
Klasy public class Simple // partial abstract sealed public class Simple // partial abstract sealed { public int Liczba = 9; public static double Ułamek = 0.21 ; // 0 string Napis ; // private public int Suma ( int Liczba ) { return this.Liczba + Liczba ; } public static double Mar( double Cena ) return Ułamek * Cena ;
// przeciążony k. domyślny { Liczba = 5 ; public Simple ( ) // przeciążony k. domyślny { Liczba = 5 ; } // nie można listy powiązań public Simple ( int Start ) Liczba = Start ; } public Simple ( Simple s ); Liczba = s.Liczba ;
Simple s0; // tylko zmienna referencyjna s0 = new Simple( ); // Liczba == 5 // Simple s1 = new Simple( ) ; // == 5 Simple s2 = new Simple( 9 ) ; // == 9 s2.Liczba += s2.Suma( s1.Liczba ); // == 23 Simple s3 = new Simple( s2 ); // == 23 int m = Simple.Mar( 100 ) ; // == 21 // funkcje i składowe statyczne // wywołuje się podając nazwę klasy
· modyfikatory dostępu (dla klas i dla składowych) opis public dostępne zewsząd private tylko wewnątrz klasy (domyślny dla składowych) protected dla klas dziedziczących internal tylko w pakiecie (domyślny dla klas) protected internal dla klas dziedziczących w pakiecie
· klasy wieloplikowe (2.0) // plik Prog1.cs public partial class Employee { public void DoWork() { } } // plik Prog2.cs public void GoToLunch() { }
public partial class A { } public class A { } // błąd // · ta sama przestrzeń nazw · niekonfliktowe modyfikatory typu klasy ( nie trzeba powtarzać ) public private protected internal abstract sealed · niekonfliktowa klasa bazowa i lista interfejsów WinApp
· klasy statyczne : - nie wolno tworzyć obiektu - wszystkie składowe statyczne public static class Services { public static int Data1 = 123; public static void Serv1(int param) { .... } } // int Res1 = ++ Services.Data1 ; Services.Serv1(78);
● inicjowanie obiektów klas (3.0) public class Alfa { public int al; public long fa; /* public Alfa( int a, long f) al = a; fa = f; } */ } // Alfa aa = new Alfa { al = 7, fa = 14L }; // składowe public Alfa bb = new Alfa { 7, 14L }; // błąd
public class Alfa { public int al; public long fa; private char kod; // public Alfa( char kk ) kod = kk + 5; } Alfa aa = new Alfa (0x41){ al = 7, fa = 14L }; // składowe: private public // protected DrawRect
● funkcje rozszerzające (3.0) // Fun(ob) -> ob.Fun() public static class StringExt // static { public static void Older03 (this System.String pt) { if (pt[0] > pt[3]) Console.WriteLine(pt[0]); else Console.WriteLine(pt[3]); } public static char LetterOfIndex (this System.String st, int x) { if (x < 0 || st.Length <= x) return '?'; else return st[x]; } }
string st = "Autobus."; Console.WriteLine(st.Older03()); // przekład: Older03(st) Console.WriteLine("{0}, {1}", st.LetterOfIndex(4), st.LetterOfIndex(12)); // LetterOfIndex(st,4) LetterOfIndex(st, 12) // o // b, ?
using LibOne; // biblioteka .dll // ClassOne, int X public static class LibOneExt { public static void Limit15 (this LibOne.ClassOne c1) if (c1.X > 15) c1.X = 15; } // ClassOne cc = new ClassOne(); cc.X = 27; Console.Write(cc.X.ToString() + ", "); cc.Limit15(); // Limit15(cc); Console.WriteLine(cc.X); //27, 15 Exten
Hermetyzacja · składowe prywatne i funkcje dostępu ( jak C++ ) · właściwości public class Account { private decimal amount ; private string number ; public decimal Amount // zapis i odczyt { get { return amount ; } set { if ( Authorization ( ) ) amount = value ; } } // accessors
public string Who // tylko odczyt { get { return number ; } } decimal AC ; string NC ; Account Customer = new Account ( ) ; AC = Customer.Amount ; // get_Amount Customer.Amount = AC + 100 ; // set_Amount NC = Customer.Who ; // get_Number Edit encapsulation
public class Base1 { private double price; public double Price get { return price; } protected set { price = value; } } // set dostępne w klasie Base1 i w klasach pochodnych
● właściwości automatyczne (3.0) Auto-Implemented Properties public class Point { /* private int x; private int y; public int X {get { return x; } set { x = value; } } public int Y {get { return y; } set { y = value; } } */ // public int X { get; set; } public int Y { get; set; } // nazwy zmiennym nadaje kompilator }
} public class Point { public int X { get; private set; } public int Y { get; protected set; } } // nazwy zmiennym nadaje kompilator // zmiana X tylko w klasie Point // zmiana Y tylko w klasie Point // i w klasach pochodnych
· właściwości statyczne private static string bankname = " PKO " ; private static string bankname = " PKO " ; public static string BankName ; { get { return bankname ; } set { bankname = value ; } } · składowe tylko do odczytu public readonly decimal Currency ; public static readonly string AccType = "A1"; // nadawanie wartości tylko w deklaracji lub // w konstruktorze klasy
public int X { get; set; } public int Y { get; set; } } // Typy anonimowe (3.0) public class Point { public int X { get; set; } public int Y { get; set; } } // var TTT = new {T1 = new Point { X = 4, Y = 4 }, T2 = new Point { X = 7, Y = 7 }, T3 = new Point { X = 2, Y = 2 } }; // klasa lokalna opisująca trójkąt Console.WriteLine(TTT.GetType()); //f__AnonymousType0`3[CS3.Point,CS3.Point,CS3.Point] Console.WriteLine(TTT.ToString()); //{ T1 = CS3.Point, T2 = CS3.Point, T3 = CS3.Point }
Wiązania dynamiczne ( 4.0 ) public object NowyKlient( ... ) { object kli = null; if ( ... ) kli = new Klient_A(); else kli = new Klient_B(); ... return kli; } // Klient_A nowy = (Klient_A) NowyKlient( ... ); if( nowy != null ) { nowy.Nazwisko = "Nowak"; }
dynamic nowy = NowyKlient( ... ); nowy.Nazwisko = "Nowak"; // poprawnie nowy.NieistniejącaFunkcja ( ); // błąd wykonania (nie kompilacji) · również zmienne proste dynamic liczba = 125.54; double ile = liczba / 3.22 ; // poprawne liczba = "Napis"; // poprawne char cc = liczba[0]; // 'N'
· dynamiczne statyczne Klient_B kli = new Klient_B(); dynamic dynKli = kli; // statyczna do dynamicznej Klient_B natręt = dynKli; // dynamiczna do statycznej Dyna
Przeciążanie operatorów public class Line { public int Low , High ; // public static Line operator + // op. binarny ( Line L1 , Line L2 ) int a , b; a = L1.Low < L2.Low ? L1.Low : L2.Low; b = L1.High > L2.High ? L1.High : L2.High; return new Line { Low = a , High = b } ; } // musi być funkcja statyczna
public static int operator * (Line L1, int x) // operator binarny { return L1.Low * x; } // Line L = new Line { Low = –2 , High = 7 } ; Line K = new Line { Low = 0 , High = 9 } ; Line LK = L + K ; // ( -2 , 9 ) int Z = LK * 5 ; // -10
public static Line operator + (Line db) // operator unarny { return new Line { Low = db.Low, High = db.High + 10 }; } public static Line operator ++ (Line no) // operator unarny, pre/post nierozróżnialne return new Line {Low = no.Low – no.High, High = no.High - 1 }; } OpOver
Table 12-1. Overloadability of C# Operators +, -, !, ~, ++, --, true, false These unary operators can be overloaded. +, -, *, /, %, &, |, ^, <<, >> These binary operators can be overloaded. ==, !=, <, >, <=, >= These comparison operators can be overloaded. C# demands that “like” operators ( i.e., < and >, <= and >=, == and != ) are overloaded together. [ ] The [ ] operator cannot be overloaded. Use the indexer construct. ( ) The () operator cannot be overloaded. Use custom conversion methods. +=, -=, *=, /=, %=, &=, |=, Shorthand assignment operators cannot be overloaded; ^=, <<=, >>= however, you receive them as a freebie when you overload the related binary operator. Andrew Troelsen, Pro C# 2010 and the .NET 4 Platform, Fifth Edition, Apress.
Indeksatory class Zasobnik { public int[] dane = new int[100]; public int this[int ix] { get { return dane[ix]; } set { dane[ix] = value; } } } // Zasobnik zz = new Zasobnik(); zz[9] = 15; int alfa = zz[9]; Indexer
Definiowanie Konwersji konwersja jawna public static explicit operator Okrąg ( Odcinek oo ) { Okrąg ok = new Okrąg(); if (oo.X > oo.Y) { ok.Sx = oo.X; ok.Sy = oo.Y; } else { ok.Sx = oo.Y; ok.Sy = oo.X; } ok.Pr = Math.Abs(oo.X + oo.Y); return ok; } // Okrąg oki = ( Okrąg ) odcinek; // jawna
konwersja implikowana public static implicit operator Okrąg ( Odcinek oo ) { Okrąg ok = new Okrąg(); ok.Sx = oo.X; ok.Sy = 0; ok.Pr = oo.Y * oo.Y; return ok; } // Okrąg oki = odcinek; // implikowana · nie wolno w tej samej klasie zdefiniować obydwu konwersji ale implikowana zastępuje jawną CustConv
Relacja całość - część public class Radio { private string Make ; public void OnOff ( bool on ) { ... } public Radio ( string name ) Make = name ; }
public class Car { private string PetName ; private Radio radio ; public Car( string music , string name ) { radio = new Radio ( music ); PetName = name ; } public MakeNoice ( bool on ) radio.OnOff ( on ); }} Car MyFirst = new Car ( "Eltra", "Kaszel" ) ; MyFirst.MakeNoice ( true );
Klasy zagnieżdżone public class Car { private class Radio //(1) { public void OnOff ( bool on ) {if (on) Console.WriteLine("Booom!"); } } private Radio radio = new Radio ( ); //(2) // obiektów klasy Radio nie można tworzyć // poza klasą Car (private) Car.Radio rd = new Car.Radio(); // błąd
// po zmianie private -> public (1) public class Radio { ... } // Car.Radio rd = new Car.Radio(); rd.OnOff(true); // Booom! // po zmianie private -> public (2) public Radio radio = new Radio(); Car ca = new Car(); ca.radio.OnOff(true); // Booom!
Dziedziczenie public class Parent { public int a ; public string b ; public Parent ( int Va , string Vb ) { a = Va ; b = Vb ; }} public class Child : Parent // pojedyncze { public long z ; public Child ( int Va , string Vb , long Vz ) : base ( Va , Vb ) { z = Vz ; } }
· składowe public są dziedziczone jako public · składowe protected są dziedziczone jako private · składowe private nie są dziedziczone // · klasy zapieczętowane public sealed class Childless { ... } public sealed class Grandson : Child
Funkcje wirtualne public class Employee { protected decimal Payment = 1000 ; public virtual void Bonus ( decimal X ) { Payment += X ; } } public class Manager : Employee { public override void Bonus( decimal X ) { Payment += 5 * X ; }
public class Proxy : Manager { public new void Bonus ( decimal X ) Payment += 700; } public class Boss : Manager public override void Bonus(decimal X ) { Payment += 12 * X ; }
Employee [ ] Team = { new Employee ( ) , new Manager ( ), new Proxy ( ), new Boss ( ) } ; for ( int i = 0 ; i < Team.Length ; ++i ) Team [ i ] . Bonus ( 100 ); // 1100 , 1500 , 1500 , 2200 Proxy wice = new Proxy ( ) ; wice.Bounus ( 100 ) ; // 1700
· wywołanie funkcji wirtualnej z klasy bazowej public override Draw ( ) { . . . . . . . . . . . . base.Draw ( ) ; .......... } Wydaw
klasy abstrakcyjne i abstrakcyjne funkcje wirtualne public abstract class Root { protected int alfa = 17; public abstract void Print( ); } public class Level1Node : Root public override void Print( ) Console.WriteLine( alfa );
Finalizacja public class Alfa { Alfa ( ) Console.WriteLine( "Oto jestem." ) ; } ~Alfa ( ) // wywoływane przez gc Console.WriteLine( "Dobranoc." ) ;
Zbieranie śmieci · generacje obiektów 0 , 1 , 2 · funkcje System.GC GC.Collect ( NrGeneracji ) //( )- wszystkie GC.GetGeneration ( obiekt ) GC.MaxGeneration ( ) GC.SupressFinalize ( obiekt ) GC.ReRegisterForFinalize ( obiekt ) GC.GetTotalMemeory ( ) Fina
Pliki dyskowe i serializacja · przestrzeń nazw System.IO · informacje o plikach i katalogach - abstrakcyjna klasa bazowa FileSystemInfo Name Attributes Exists CreationTime ... - klasy pochodne FileInfo DirectoryInfo · klasy Directory , File
przetwarzanie katalogów klasa DirectoryInfo DirectoryInfo dir1, dir2 ; dir1 = new DirectoryInfo ( @"C:\MyApp" ) ; dir2 = new DirectoryInfo ( "." ) // bieżący, zawierający *.exe Create ( ) Delete ( ) GetFiles ( ) GetDirectories ( ) MoveTo ( ) DirInfo
· przetwarzanie plików klasa FileInfo Open( ) Delete( ) MoveTo( ) OpenRead( ) OpenWrite( ) · parametry otwarcia pliku FileMode. Append Create Open OpenOrCreate Truncate FileAccess. Read ReadWrite Write FileShare. None Read ReadWrite Write
· wynikiem funkcji Open ( ) jest referencja obiektu klasy FileStream umożliwiającego zapis/odczyt do/z pliku bez formatowania ( ciąg bajtów ) FileInfo ff = new FileInfo (@"C:\Temp\Data.txt"); FileStream fs = ff.Open (FileMode.Open , FileAccess.Read); // albo FileStream fs = new FileStream ("Plik.bin", FileMode.Open, FileAccess.Read);
· właściwości i funkcje klasy FileStream CanReed CanWrite CanSeek Length Position Read ( ) ReadByte ( ) Write ( ) WriteByte ( ) Seek ( ) Flush ( ) Close ( ) // ciągi bajtów byte [ ] TaBa = new byte [ 100 ]; // for ( int i = 0 ; i < TaBa.Length ; ++i ) TaBa [ i ] = (byte) fs . ReadByte( ); // albo fs.Read ( TaBa, 0, TaBa.Length );
fs.Seek(0L, SeekOrigin.Begin); // .Current // .End // albo fs.Position = 0; for ( int i = 0 ; i < TaBa.Length ; ++i ) fs . WriteByte( TaBa[ i ]); // albo // fs.Write(TaBa, 0, Taba.Length);
· wykrywanie końca pliku int Count = 0; while (Count++ < fs.Length) { ..... } // albo if (fs.Position != fs.Length) · zamykanie pliku fs.Close( ); FileInfo
· zapis/odczyt z formatowaniem klasy Object TextReader TextWriter BinaryReader StreamWriter BinaryWriter StreamReader StringWriter StringReader
TextWriter TextReader · podstawowe funkcje TextWriter TextReader Write ( ) Peek ( ) WriteLine ( ) Read ( ) Flush ( ) ReadLine ( ) Close ( ) ReadToEnd ( )
FileInfo fi = new FileInfo ( @"C:\Temp\Test.txt" ) ; // klasa pochodna TextWriter StreamWriter sw = fi . CreateText ( ) ; // albo StreamWriter sw = new StreamWriter("dane.txt"); // // klasa pochodna TextReader StreamReader sr = fi . OpenText ( ) ; StreamReader sr = new SteamReader("dane.txt");
int a = 398 ; double x = 122.453E-42 ; sw.WriteLine ( " Some text. " ) ; // 1 arg sw.Write ( a + " ") ; sw.Write ( x.ToString ( ) ) ; sw.Close ( ) ; // string str ; str = sr.ReadLine ( ) ; a = int.Parse ( sr.ReadLine ( ) ) ; x = double.Parse ( sr.ReadLine ( ) ) ; sr.Close ( );
· wykrywanie końca pliku sr.ReadLine() == null // funkcja // albo sr.EndOfStream // właściwość StreamRW
· podobnie StringReader StringWriter StringWriter stw = new StringWriter(); stw.WriteLine("Tekst ćwiczebny."); // 1 arg stw.WriteLine( a ); stw.Close(); StringReader str = new StringReader ( stw.ToString() ); string st = str.ReadLine(); a = int.Parse ( str.ReadLine ( ) ) ; str.Close();
BinaryWriter BinaryReader · klasy BinaryReader BinaryWriter BinaryWriter BinaryReader Write ( ) PeekChar ( ) Seek ( ) Read ( ) Flush ( ) ReadXXX ( ) Close ( ) XXX : Boolean, Byte, Bytes, Char, Chars, Int16, Int32, Int64, Double, Decimal,... BinaryRW
serializacja automatyczne zapisywanie / odczytywanie obiektów klas do / z pliku using System.Runtime.Serialization. Formatters.Binary ; using System.IO ; // [Serializable] public class Radio { public string Make ; [NonSerialized] private int something ; // nie zapisywane public bool On ; }
Radio radio = new Radio ( ) ; radio.Make = "Aiwa" ; radio.On = true ; // FileStream data = File.Create ("Radio.dat"); BinaryFormatter bifoter = new BinaryFormatter(); bifoter.Serialize ( data , radio ) ; data.Close ( ) ; data = File.OpenRead ( "Radio.dat" ) ; Radio nn = (Radio)bifoter.Deserialize( data ); Seria
System.Collections // usunąć Generics Klasy kolekcji System.Collections // usunąć Generics · klasy ArrayList // lista dowolnych obiektów Queue // kolejka FIFO Stack // stos LIFO SortedList // posortowana lista par // <klucz, wartość> Hashtable // tablica par // <klucz, wartość > // kodowanie mieszające
· ArrayList // tablica dowolnych obiektów Add, BinarySearch, Clear, Clone, Contains, CopyTo, IndexOf, Insert, Remove, Reverse, Sort // funkcje Capacity, Count // właściwości · Queue // kolejka FIFO Enqueue, Dequeue, Peek, Clear, Contains // funkcje Count // właściwość · Stack // stos LIFO Push, Pop, Peek, Clear, Contains // funkcje
· SortedList // lista par <klucz, wartość> // posortowana Add, Clear, ContainsKey, ContainsValue, GetByIndex, IndexOfKey, IndexOfValue, Remove, SetByIndex // funkcje Capacity, Count, Item // właściwości // KeyValuePair – klasa pomocnicza · Hashtable // tablica par <klucz, wartość > // kodowanie mieszające Add, Clear, ContainsKey, ContainsValue, Remove // funkcje Capacity, Count, Item // właściwości
public class Auto { public string Name; public double Price; public Auto(string nn, double pp) Name = nn; Price = pp; }
ArrayList al = new ArrayList(); al.Add ( new Auto("A", 100) ); al.Add ( new Auto("B", 20) ); Console.WriteLine("{0}, {1}", ((Auto)al[0].Price, ((Auto)al[1]).Price); // 100, 20
SortedList sl = new SortedList(); sl.Add ( "zero", new Auto("A", 100) ); sl.Add ( "jeden", new Auto("B", 20) ); // Console.WriteLine("{0}, {1}, {2}, {3}", ((Auto)sl["zero"]).Price, ((Auto)sl["jeden"]).Price; // 100, 20 ((Auto)sl.GetByIndex(0)).Price, ((Auto)sl.GetByIndex(1)).Price); // 20, 100
generics, typy parametryczne, typy uogólnione Wzorce klas kolekcji generics, typy parametryczne, typy uogólnione Dictionary <key, value> SortedDictionary <key, value> LinkedList <type> // dwukierunkowa List <type> // jednokierunkowa SortedList <key, value> // indeksowanie Queue <type> Stack <type>
sl.Add("C", "alfa"); // kompilacja ok SortedList sl = new SortedList(); sl.Add(12, 5.5); sl.Add("B", 9); sl.Add("C", "alfa"); // kompilacja ok // błąd wykonania, porównanie kluczy niemożliwe
SortedList <string, int> al = new SortedList <string, int> (); al.Add("X", 5); al.Add("Y", 7); al.Add("Z", 3); al.Add(5, 2); // błąd kompilacji al.Add("K", 3.2); // błąd kompilacji // Console.WriteLine("{0}, {1}, {2}", al["X"], al["Y"], al["Z"]); // 5, 7, 3
· wzorce kolekcji we wzorcach funkcji class Osoba { public string Imie; public string Nazwisko; public Osoba(string s1, string s2) { Imie = s1; Nazwisko = s2; } public overrite string ToString( ) return Imie + " " + Nazwisko; } }
public void Dopisz <T> (List <T> li, params T [ ] dane ) { foreach ( T elem in dane ) li.Add( elem ); } // List <Osoba> lios = new List <Osoba>(); Dopisz(lios, new Osoba("Adam", "Kot"), new Osoba("Anna","Kotka")); foreach (Osoba os in lios) Console.WriteLine( os );
Interfejsy · określają operacje realizowane przez klasę lub jej cechy charakterystyczne · klasy abstrakcyjne zawierające deklaracje funkcji abstrakcyjnych public interface INodes_F { int GetNumberOfNodes ( ); } // funkcja abstrakcyjna // lub public interface INodes_P { int Nodes {get; set;} } // właściwość abstrakcyjna
public abstract class Shape { public int Nodes ; public double Surface; } // public class Hexagon : Shape , INodes_F public int GetNumberOfNodes ( ) return 6 ;
public class Triangle : Shape , INodes_F { public int GetNumberOfNodes ( ) return 3 ; } // public class Circle : Shape ...
Hexagon hex = new Hexagon ( ); if ( hex is INodes_F ) ..... ; // test // INodes_F inodes1 = (INodes_F) hex ; // InvalidCastException INodes_F inodes2 = hex as INodes_F ; // NULL int NodesOfHex = inodes1.GetNumberOfNodes ( ) ; · zmienne reprezentujące interfejsy ( referencje ) mogą być parametrami funkcji · interfejs jako typ może być wynikiem funkcji Dzie&Int
· hierarchie interfejsów interface IDrawBW { void DrawBW ( ) ; } interface IDrawGS : IDrawBW void DrawGS ( ) ; interface IDrawCR : IDrawGS void DrawCR ( ) ;
public class Picture : IDrawCR { // implementacja funkcji // DrawCR , DrawGS , DrawBW } // Picture pp = new Picture ( ) ; IDrawCR iCR = pp as IDrawCr ; iCR . DrawBW ( ) ; iCR . DrawGS ( ) ; iCR . DrawCR ( ) ;
Interfejsy standardowe System.Collections · interfejsy ICollection IDictionary IDictionaryEnumerator IHashCodeProvider IList IComparer // IEnumerable IEnumerator IClonable IComparable
· przeglądanie kolekcji Library EhRL = new Library ( 100000 ) ; foreach ( Book bb in EhRL ) { ... } ; // wymaga w IEnumerable oraz IEnumerator // w klasie Library public class Library : IEnumerable, IEnumerator { private Book [ ] BookArr ;
// implementacja IEnumerable public IEnumerator GetEnumerator ( ) { return ( IEnumerator ) this ; } // implementacja IEnumerator public void Reset ( ) { .... } public bool MoveNext ( ) { ... } public object Current get { .... } } }
public class DaysOfTheWeek : IEnumerable - iteratory (2.0) public class DaysOfTheWeek : IEnumerable { string[] m_Days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" }; public IEnumerator GetEnumerator() { for (int i = 0; i < m_Days.Length; i++) yield return m_Days[i]; } } // DaysOfTheWeek week = new DaysOfTheWeek(); foreach (string day in week) System.Console.Write(day + " "); Iterat
· pełne kopiowanie public class Point { public int x , y ; public Point (int A , int B ) { x = A ; y = B ; } Point AA , BB ; AA = new Point ( 5, 7) ; BB = AA ; // AA i BB wskazują ten sam // obiekt na stercie (shallow)
// pełne kopiowanie wymaga ICloneable public class Point : ICloneable { public int x , y ; public Point (int A , int B ) { x = A ; y = B ; } public object Clone ( ) return new Point( this.x , this.y ); } BB = (Point)AA.Clone(); // nowa kopia
· sortowanie public class Point : IComparable { public int X, Y; public int CompareTo ( object ob ) // { < == > } -> { - 0 + } { Point temp = (Point) ob; if ( this.X > temp.X ) return 1; if ( this.X == temp.X ) return 0 ; return -1; }} Point [ ] aP = new Point [ 100 ]; Array.Sort(aP); // aP[3].CompareTo((object)aP[7]) SortP, Komis
· interfejsy parametryczne, generics ICollection < T > IComparer < T > IDictionary < TKey, TValue > IEnumerable < T > IEnumerator < T > IEqualityComparer < T > IList < T >
· klasy, kolekcje i interfejsy parametryczne public class Dict<KeyType, EleType > where KeyType: IComparable<KeyType> { Dictionary<KeyType, EleType> dd = new Dictionary<KeyType,EleType>(); public KeyType patt; public void Add(KeyType key, EleType val) { if (key.CompareTo(patt) != 0 && !dd.ContainsKey(key)) dd.Add(key, val); } }
Dict<int, string> dis = new Dict<int,string>(); dis.patt = 25; dis.Add(24, "alfa"); dis.Add(25, "beta"); dis.Add(26, "delta"); dis.Add(26, "gamma"); // {24, alfa}, {26, delta}
Delegacje · klasy, których obiekty udostępniają funkcje · klasy pochodne System.MulticastDelegate Składowe klasy System.MulticastDelegate składowa opis Method nazwa funkcji zawartej w delegacji Target nazwa klasy, w której zdefiniowana jest funkcja lub null dla statycznych Combine( ), +, += dodanie funkcji GetInvocationList ( ) lista funkcji zawartych w delegacji Remove( ), -, -= usunięcie funkcji
delegate double Fun(double x, out bool ok); // nowy typ // funkcje nazwane double Sqrt(double x, out bool ok) { if ( x >= 0 ) { ok = true; return Math.Sqrt( x ); } else { ok = false; return 0; } } // double Log (double x, out bool ok) { ..............................}
double z, x = 4.3; bool dobrze = true; Fun funkcja = new Fun ( Sqrt ); // obiekt delegacji // albo Fun funkcja = Sqrt; // wywołanie z = funkcja ( x, out dobrze ); // sqrt // funkcja = Log; z = funkcja ( x, out dobrze ); // log if (funkcja != null) ...
· tablice delegacji Fun [] TabFun = new Fun[2]; TabFun[0] = new Fun(Sqrt); TabFun[1] = Log; // po ustaleniu indeksu z = TabFun[indeks](x, out dobrze); // double [] Args = {2.34, 5.32}; double [] Results = { TabFun[0](Args[0], out dobrze); TabFun[1](Args[1], out dobrze); };
· delegacje wielokrotne (multicast) void AsIs(string s) { Console.WriteLine(s); } // void Vers(string s) Console.WriteLine(s.ToUpper( ));
delegate void Print2(string s); // Print2 Both = AsIs; Both += Vers; Both("Ala ma kota."); // Ala ma kota. // ALA MA KOTA. Both -= AsIs; Both("Ola ma psa."); // OLA MA PSA if (Both != null) ... Dele, MulDele, EwideD
· delegacje anonimowe (2.0) button1.Click += // delegacja Click delegate(System.Object o, System.EventArgs e) { MessageBox.Show("Click!"); }; // delegate int Del( int x ); static int n = 79; // składowa klasy int m = 2; // zmienna lokalna Del d = delegate( int k ) { return n + m + k + 3; }; int F = d(5); // 89 Anonymous
· kowariancja i kontrawariancja delegacji (2.0) ( covariance and contravariance ) class Mammal { ... } // bazowa class Dog : Mammal { ... } // pochodna // public delegate Mammal Handler( ); // delegacja public Mammal FirstHandler( ) { return new Mammal( ); } public Dog SecondHandler( ) { return new Dog( ); } Handler handler1 = FirstHandler; Handler handler2 = SecondHandler;// kowariancja
public delegate void Vet ( Dog ); // delegacja public void FirstHandler(Dog ds) { ... } public void SecondHandler ( Mammal ms ) { ... } // Vet handler1 = FirstHandler; Vet handler2 = SecondHandler; // kontrawariancja
● wzorce delegacji (generics) (3.0) delegate R Fun <R, A>(A arg); // Fun <long, int> d1; long FK (int x) { return (long)x + 1000000L; } d1 = FK; Fun <double, double> d2; Fun <char, int> d3;
● systemowe wzorce delegacji bezwynikowe public delegate void Action <in T> ( ) public delegate void Action <in T> ( T arg ) public delegate void Action<in T1, in T2> ( T1 arg1, T2 arg2 ) // ……………………………………………………………………………… public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16> ( T1 arg1, . . . . T16 arg16 ) // Action <string> messageTarget; messageTarget = Console.WriteLine; messageTarget("Hello, World!");
public delegate TResult Func <out TResult>( ) B. z wynikiem public delegate TResult Func <out TResult>( ) public delegate TResult Func <in T, out TResult> ( T arg ) //……………………………………………………………………………………………… public delegate TResult Func <in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16, out TResult> ( T1 arg1, . . . , T16 arg16 ) // Func <string, string> convertMethod = OnlyLetters; //…………………………………………………………………………………………………… string name = "Dakota512"; Console.WriteLine(convertMethod(name)); convertMethod = OnlyDigits;
● wyrażenia lambda (funkcje nienazwane) (3.0) - jeden argument delegate R Fun <R, A>(A arg); // Fun <int, int> L1 = x => x * x + 1; // λ x . x * x + 1 Console.WriteLine( L1(12) ); // 145 Fun <double, int> L2 = x => (double)x / 2 + 0.5; Console.WriteLine( L2(7) ) ; // 4,0
wiele argumentów delegate R Arg2 <R, A, B> (A x, B y); // Arg2 <long, int, char> suma = (x,y) => (long)(x + y + 1); Console.WriteLine(" Suma : " + suma(15, 'A'). ToString()); // Suma : 81 Lambda
· Use a delegate when: - An eventing design pattern is used. - The caller has no need access other properties, methods, or interfaces on the object implementing the method. - Easy composition is desired. - A class may need more than one implementation of the method.
· Use an interface when: - There are a group of related methods that may be called. - A class only needs one implementation of the method. - The class using the interface will want to cast that interface to other interface or class types. - The method being implemented is linked to the type or identity of the class: for example, comparison methods.
Zdarzenia · zgłoszenie zdarzenia powoduje wywoływanie wszystkich funkcji zawartych w delegacji powiązanej z tym zdarzeniem public class Car { private float Gas ; public delegate void GasShortage ( string msg ) ; public event GasShortage Yellow ; public event GasShortage Red ;
public void SpeedUp ( double speed ) { if ( Gas < 2 && Yellow != null ) Yellow ( "Only " + Gas.ToString ( ) + " gallons of gas !" ); if ( Gas < 0.5 && Red != null ) Red ( "Almost no gas !" ) ; }
public class Driver { private Car MyCar = new Car( ); public void Driving ( ) { MyCar.Yellow += new Car.GasShortage ( YellowLight ); MyCar.Red += new Car.GasShortage ( RedLight ) ; } public void Parking ( ) { MyCar.Yellow -= new Car.GasShortage ( YellowLight ) ;
public static void YellowLight (string msg ) { Console.WriteLine ( msg ); } public static void RedLight (string msg ) Alarm ( ) ; Event, Loteria
Obsługa wyjątków throw nazwa_wyjątku // obiekt klasy dziedziczącej z System.Exception try { ...... } catch ( typ_wyjątku ) .............. catch // wszystkie wyjątki finally Exep
Zapytania ( 3.0 ) wyrażenia zapytaniowe - querry expressions przestrzeń nazw LINQ - Language-Integrated Query 3 etapy : 1. określenie źródła danych, 2. utworzenie zapytania, 3. wykonanie zapytania.
class FirstLINQ { static void Main() { int[] numbers = // 1. Data source. new int[7] { 0, 1, 2, 3, 4, 5, 6 }; // 2. Query creation. var numQuery = from num in numbers where (num % 2) == 0 select num; // 3. Query execution. foreach (int elem in numQuery) { Console.Write("{0} ", elem); }}}
IQueryable< > , IQueryProvider technologie LINQ Linq to Objects Linq to DataSet Linq to SQL Linq to XML Linq to own sources IQueryable< > , IQueryProvider J. Matulewski, C# 3,0 i .Net. 3.5 Technologia LINQ, Helion, 2008 Przykłady : http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx IEnumerable IEnumerable< >
słowa kluczowe from // źródło danych where // filtrowanie danych select // pobieranie danych join // łączenie danych orderby // sortowanie danych ascending // rosnąco descending // malejąco let // nadanie wartości group // grupowanie danych into // kontynuacja zapytania on // połącz tabele equals // równość pól
funkcje rozszerzające IEnumerable, IEnumerable< > Select, SelectMany // pobieranie danych OrderBy, ThenBy, OrderByDescending, ThenByDescending, Reverse // sortowanie Where // filtrowanie Aggregate, Average, Count, LongCount, Max, Min, Sum // artymetyczne Cast, OfType, ToArray, ToDictionary, ToList, ToLookup, ToSequence // konwersja Element, DefaultIfEmpty, ElementAt, ElementAtOrDefault, First, FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault // pobieranie elementu
EqualAll // porównywanie Empty, Range, Repeat // tworzenie GruopBy // grupowanie GroupJoin, Join // łączenie Skip, SkipWhile, // pomijanie Take, TakeWhile // wybór All, Any, Contains // kwantyfikatory Concat, Distinct, Exept, Intersection, Union // operacje na zbiorach
Func<string, string> selector = str => str.ToUpper(); public static IEnumerable<TResult> Select <TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector) // Func<string, string> selector = str => str.ToUpper(); string[] words = { "orange", "apple", "Article", "elephant" }; var aWords = words.Select(selector); foreach (string word in aWords) Console.WriteLine(word);
Linq to own sources -> Linq to Objects -> Linq to own sources -> Linq1 Linq2
Współbieżność · przestrzeń nazw System.Threading · klasa Thread tworzenie wątków i zarządzanie ich wykonywaniem · główne funkcje Start Suspend Resume Abort Sleep GetHashCode · główne właściwości CurrentThread Name ThreadState Priority IsBackGround IsAlive
· priorytety wątków Lowest BelowNormal Normal AboveNormal Highest · wątki pierwszoplanowe i drugoplanowe ( ForeGround / BackGroung Threads ) – dopóki istnieje przynajmniej jeden wątek pierwszoplanowy aplikacja nie jest zamykana przez CLR – po zakończeniu ostatniego wątku pierwszoplanowego CLR kończy wszystkie aktywne jeszcze wątki drugoplanowe
public class Worker { public bool EndOfWork = false ; public void DoWork ( ) // funkcja wątku { Console.WriteLine ("Worker's ID is {0}\n" + "Worker's name is {1}", Thread.CurrentThread.GetHashCode ( ) , Thread.CurrentThread.Name ) ; for ( int i = 0; i < 1000 && !EndOfWork ; ++i ) { Console.WriteLine ( i ) ; Thread.Sleep ( 500 ) ; } } // End of Worker
static void Main ( string [ ] args ) { Worker ww = new Worker ( ) ; Thread job = new Thread( new ThreadStart( ww.DoWork )); // delegacja ThreadStart // funkcja bezargumentowa job.Name = "Ben" ; job.Start ( ) ; Thread.Sleep ( 5000 ); job.Suspend ( ) ; ww.EndOfWork = true ; job.Resume ( ) ; }
// funkcje z argumentami class AddParams // klasa argumentu { public int a, b; public AddParams(int numb1, int numb2) a = numb1; b = numb2; }
class Program { void Add(object data) // funkcja wątku if (data is AddParams) AddParams ap = (AddParams)data; Console.WriteLine("{0} + {1} is {2}", ap.a, ap.b, ap.a + ap.b); }
void Run ( ) { AddParams ap = new AddParams(10, 10); Thread t = new Thread( new ParameterizedThreadStart(Add)); t.Start(ap); // przyśnij, aby drugi wątek // zakończył pracę Thread.Sleep(50); } ParamThread
· asynchroniczne wykonywanie delegacji public delegate int BinaryOp(int x, int y); int Add(int x, int y) { Thread.Sleep(5000); return x + y; } // BinaryOp b = new BinaryOp(Add); // wywołanie synchroniczne, ten sam wątek int answer = b(10, 10); // lub int answer = b.Invoke(10, 10);
// asynchronicznie, odrębny wątek BinaryOp b = new BinaryOp(Add); // Start secondary thread IAsyncResult iftAR = b.BeginInvoke(10, 10, null, null); // Do other work on primary thread... int answer = b.EndInvoke(iftAR); Console.WriteLine("10 + 10 is {0}.", answer); AsyncDel
// funkcje zwrotne bool Ready = false; void AddComplete(IAsyncResult itfAR) { Console.WriteLine("Your addition is ready"); Ready = true; } // IAsyncResult iftAR = b.BeginInvoke(10, 10, new AsyncCallback(AddComplete), null); while (!Ready) { // other work is performed here... } int answer = b.EndInvoke(iftAR); AsyncCall
· wykonywanie cykliczne void PrintTime(object state) { Console.WriteLine("Time is: {0}", DateTime.Now.ToLongTimeString()); } TimerCallback timeCB = new TimerCallback(PrintTime); Timer t = new Timer(timeCB, null, 0, 1000); // delegacja, parametr, // opóźnienie startu, interwał // wątek drugoplanowy Timer
· synchronizacja dostępu do obiektów współużytkowanych ─ lock ( słowo kluczowe ) ─ System.Treading.Semaphore ─ System.Treading.Mutex ─ System.Treading.Monitor ─ System.Treading.Interlocked ─ synchronizacja za pomocą zdarzeń ─ atrybut wykluczania
public class SharedData_1 { private Records [ ] DataBase ; object UpdateLock; public Update ( string str ) { lock ( UpdateLock ) ........... // aktualizacja } Adders
public Semaphore sem1 = new Semaphore ( init_val, max_val ); // count = init_val public class SharedData_2 { private Records [ ] DataBase ; public Update ( string str ) { sem1.WaitOne( ); // if ( count != 0 ) --count; else wait; ........... // aktualizacja sem1.Release( ); // ++count; } } // wątki nie są identyfikowane
public Mutex mut1 = new Mutex ( ); public class SharedData_2 { private Records [ ] DataBase ; public Update ( string str ) { mut1.WaitOne( ); // request ownership // of a mutex ........... // updating mut1.ReleaseMutex( ); // release ownership } } // wątki są identyfikowane
public class SharedData_3 { private Records [ ] DataBase ; object UpdateObject; public Update ( string str ) { try { Monitor.Enter ( UpdateObject ) ........... // aktualizacja } finally // zawsze się wykona Monitor.Exit ( UpdateObject ) ; } } } // .TryEnter .Wait() .Pulse()
public class MainCounter // Interlocked { private long Counter = 0; public void Inc ( ) // + 1 Interlocked.Increment( ref Counter ); } public void Dec ( ) // - 1 Interlocked.Decrement( ref Counter ); }
public void Exch ( ref Value ) // { Interlocked.Exchange( ref Counter, ref Value ); } public void CompExch ( val1, val2 ) Interlocked.CompareExchange ( ref Counter, val1, val2 ); } // if (Counter == val1) // Counter = val2;
· synchronizacja ścieżek za pomocą zdarzeń ─ ManualResetEvent (true / false) ─ AutoResetEvent (true / false) ─ Reset() false ─ Set() true ─ WaitOne() : Manual bz Auto false, gdy było true ResetEvent
· atrybut wykluczania Synchronization using System.Runtime.Remoting.Contexts; // Thread safe [Synchronization] class Services : ContextBoundObject { public void Read ( ... ) { ... } public void Print ( ... ) { ... } public void Update ( ... ) { ... } } // wszystkie funkcje wykonywane niepodzielnie
· pula wątków CLR ─ powołanie nowego wątku ( async delegate ) powoduje uruchomienie jednego z oczekujących wątków utworzonych dla programu przez CLR ─ można do kolejnych wątków puli przypisywać funkcje do wykonania ( poprzez delegację WaitCallback ) - wątki drugoplanowe public class Printer { public void PrintNumbers() { ... } }
Printer prin = new Printer(); WaitCallback workItem = new WaitCallback(PrintTheNumbers); // Queue the method ten times. for (int i = 0; i < 10; i++) ThreadPool.QueueUserWorkItem(workItem, prin); // void PrintTheNumbers(object state) { Printer task = (Printer)state; task.PrintNumbers(); } ResetEventPool, PrinterPool
· współbieżne wykonywanie zadań TPL – Task Parallel Library using System.Threading.Tasks; ─ współbieżne przetwarzanie rozłącznych zbiorów danych Parallel.For ( from, to, action ) Parallel.ForEach ( data_source, action ) // również z dodatkowymi parametrami
Parallel.For ( 0, 4, DoWork ); // powołanie 4 wątków (0, 1, 2, 3), // z których każdy wykonuje funkcję // zawartą w delegacji DoWork DataPara/MatMul Parallel.ForEach ( kolekcja, DoWork ) ; // powołanie max. tylu wątków ile // elementów zawiera kolekcja, // każdy wątek wykonuje funkcję // zawartą w delegacji DoWork DataPara/PictRev
─ współbieżne obliczenia Parallel.Invoke( action [ ] ac_list) // powołanie dla każdej akcji z ac_list // wątka wykonującego tę akcję ─ przerwanie wykonania wszystkich ścieżek CancelationToken TaskPara
─ klasa Task<TResult> // zadanie o wyniku ─ klasa TaskFactory // zbiór zadań // wykonywanych // współbieżnie Task.Factory.ContinueWhenAll( Task<TResult> [ ] TaskTable, Action<Task<TResult>> DoNext ) ; TaskFact
· współbieżne zapytania PLINQ AsParallel() WithCancellation() WithDegreeOfParallelism() // private CancellationTokenSource cancelToken = new CancellationTokenSource() cancelToken.Cancel();
int[] modThreeIsZero = null; // source – vector of integers try { modThreeIsZero = (from num in source.AsParallel(). WithCancellation(cancelToken.Token) where num % 3 == 0 orderby num descending select num.ToArray(); } catch (OperationCanceledException ex) Console.WriteLine( ex.Message ); ParLinq
Przestrzeń nazw · łączy zdefiniowane typy ( klasy, struktury, delegacje, zdarzenia, wyliczenia) using System ; namespace MySpace { public class Alfa { ... } public class Beta { ... } ......... } · gdy definicje klas w kilku plikach należy powtórzyć deklarację namespace
· korzystanie z przestrzeni nazw w innej przestrzeni using System ; using MySpace ; namespace NextSpace { public class Alfa_1 : Alfa { ..... } public class Alfa_2 : MySpace.Alfa // gdy konfliktowe nazwy { .... } }
· przestrzeń nazw definiująca stałe namespace Constants { public sealed class CT { public static readonly double pi = 3.1415926536 ; e = 2.7182818285 ; private CT( ) {} } using Constants ; double radius = 23.4 ; double perimeter = 2.0 * CT.pi * r ;
Pakiety i odzwierciedlenie ( refleksja ) typów · pakiet ( assembly ) ─ aplikacja ─ biblioteka Nagłówek .exe Manifest ....... Metadane Typów CIL Zasoby
· składniki przestrzeni nazw System.Reflection · składniki przestrzeni nazw System.Reflection Klasa Opis Assembly wczytanie pakietu, analiza manifestu lista typów ( klas , struktur ) AssemblyName wersja, ustawienia regionalne MethodInfo opis funkcji składowej ParameterInfo opis parametru PropertyInfo opis właściwości FieldInfo opis danej składowej
· tworzenie biblioteki .dll typ projektu: Class Library np. CarTuneUpLib CarTuneUpLib.dll public Garage : WashCar() ,ChangeOil() ... · korzystanie z biblioteki za pomocą Add Reference dodać bibliotekę CarTuneUpLib // using CarTuneUpLib ; public static int Main ( string [ ] args ) { Garage BlueNut = new Garage ( ) ; BlueNut.ChangeOil ( ... ) ; ............. }
· dynamiczne ładowanie biblioteki using System ; using System.Reflection ; using System.IO ; Assembly a = Assembly.Load ( "CarTuneUpLib" ); // CarTuneUpLib.dll tam gdzie .exe // klasy Type [ ] Classes = a.GetTypes( ); // odczytywanie składowych Type garage = a.GetType("CarTuneUpLib.Garage"); MemberInfo [ ] mi = garage.GetMembers( ); // podobnie parametry funkcji
· dynamiczne wywoływanie funkcji // tworzenie klasy object Gar = Activator.CreateInstance(garage); // MethodInfo wash = garage.GetMethod("WashCar"); wash.Invoke( Gar, null ); // bezargumentowa object [ ] TabPar = { par1, par2, ... }; xxx.Invoke ( obj, TabPar ); // z argumentami
· pakiety prywatne i współużytkowane ( Global Assembly Cache ) · pakiety prywatne i współużytkowane ( Global Assembly Cache ) · wersje pakietów współużytkowanych a.b.c.d ─ a : główny numer wersji ─ b : podrzędny numer wersji ─ c : numer kolejny kompilacji ─ d : liczba szybkich poprawek · gdy różne a lub b wersja nieodpowiednia