Język C# ( 4.0 ) 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 1false 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 ushortUInt16 N 2 0 uint UInt32 N 4 0 ulong UInt64 N 8 0 float Single Y doubleDouble Y char Char Y 2 0 decimalDecimal Y
Deklaracje i definicje zmiennych 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 = ;
Typy implikowane (3.0) var a = 5;// int var b = 'K';// char var c = 128L;// long var d = ;// double var e = "Ala ma kota";// string a = L;// 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 = ; li32 = (int) li64;// błędna wartość //
Typy rozszerzone ( nullable ) (2.0) double? Cena;// { numbs, INF, NaN, null } // Cena = 7.54 ; // Cena = null ; // if ( Cena.HasValue ) Cena += 1.4;
Opakowanie - Rozpakowanie long aaa = , 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 typu 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 = ; 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
znaki sterujące jak w C wyłącza przetwarzanie ) string Opis1 = "\nWyniki\t:" ; string Opis2 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ń 0
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 znakznaczenie C cwaluta (wg. Windows) D dcałkowite dziesiętne E enotacja wykładnicza F fniecałkowite dziesiętne z wykładnikiem lub bez G g N n format narodowy X x postać heksydecymalna
int ii = 34; double dd = ; 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, lub // 2,523 lub 2,52345E+000 lub 2,
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(); // war = Convert.ToInt64(str);// format Console.WriteLine(war); //
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.Write("+");// o 1 w prawo Console.CursorLeft = X; // powrót Console.SetCursorPosition( X, Y ); 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 = ; a1 = a ;// a1 = checked ( a ); // wyjątek long l1 = ; a1 = l1; // błąd kompilacji a1 = ( int ) l1; // 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 = ; a1 = a ;// wyjątek a1 = unchecked ( a );
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 modyfikatoropis 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 = ; 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 ] ; // // 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 ] = ;
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 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 * 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: RankLowerUpper // 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 = ; 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 (params TyDa [ ] Liczby) { foreach (TyDa li in Liczby) Console.WriteLine(li.ToString()); // Suma + li; niepoprawne // jedynie przypisanie = } // PoLi (231.43, 99.89, );
public T Mala (T p1, T p2) where T : System.IComparable {T pom; if ( p1.CompareTo( p2 ) < 0 ) pom = p1; else pom = p2; return pom; } // p1 < p2 błąd double x; x = Mala (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
Klasy public class Simple// partial abstract sealed {public int Liczba = 9; public static double Ulamek = 0.21 ; // 0 string Napis ; // private public int Suma ( int Liczba ) { return this.Liczba + Liczba ; } internal static double Mar( double Cena ) { return Ulamek * Cena ; }
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) modyfikatoropis 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 partial class Employee { 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 ( nie trzeba powtarzać ) 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 // 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 Total // 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.Total ;// get_Amount Customer.Total = AC ;// 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 " ; 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
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 = ; 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 + ( 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 ( a, b ) ; } // musi być funkcja statyczna
public static int operator * (Line L1, int x) { 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
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
przetwarzanie katalogów klasa DirectoryInfo DirectoryInfo dir1, dir2 ; dir1 = new DirectoryInfo ) ; 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 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 [ fs.Length ]; // for ( int i = 0 ; i < fs.Length ; ++i ) TaBa [ i ] = (byte) fs. ReadByte( ); // albo fs.Read ( TaBa, 0, fs.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 TextReaderTextWriterBinaryReader BinaryWriter StreamReader StringReader StreamWriter StringWriter
TextWriter TextReader Write ( )Peek ( ) WriteLine ( )Read ( ) Flush ( )ReadLine ( ) Close ( )ReadToEnd ( ) podstawowe funkcje
FileInfo fi = new FileInfo ) ; // klasa pochodna TextWriter StreamWriter sw = fi. CreateText ( ) ; // albo StreamWriter sw = new StreamWriter("dane.txt"); // // klasa pochodna TextReader StreamReader sr = fi. OpenText ( ) ; // albo StreamReader sr = new SteamReader("dane.txt");
int a = 398 ; double x = E-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 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(); StreamRW
klasy BinaryReader BinaryWriter BinaryRW BinaryWriter BinaryReader Write ( )PeekChar ( ) Seek ( )Read ( ) Flush ( )ReadXXX ( ) Close ( ) XXX : Boolean, Byte, Bytes, Char, Chars, Int16, Int32, Int64, Double, Decimal,...
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
Klasy kolekcji System.Collections // usunąć Generics klasy ArrayList // lista dowolnych obiektów Queue // kolejka FIFO Stack // stos LIFO SortedList // posortowana lista par // Hashtable // tablica par // // 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 Count// właściwość
SortedList// lista par // posortowana Add, Clear, ContainsKey, ContainsValue, GetByIndex, IndexOfKey, IndexOfValue, Remove, SetByIndex// funkcje Capacity, Count, Item// właściwości // KeyValuePair – klasa pomocnicza Hashtable// tablica par // 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
Wzorce klas kolekcji generics, typy parametryczne, typy uogólnione Dictionary SortedDictionary LinkedList // dwukierunkowa List // jednokierunkowa SortedList Queue Stack
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 al = new SortedList (); 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 (List li, params T [ ] dane ) { foreach ( T elem in dane ) li.Add( elem ); } // List lios = new List (); 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 ( ) ; 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 {.... } }
- 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 + " ");
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 ) // { } -> { } {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 IComparer IDictionary IEnumerable IEnumerator IEqualityComparer IList
klasy, kolekcje i interfejsy parametryczne public class Dict where KeyType: IComparable { Dictionary dd = new Dictionary (); public KeyType patt; public void Add(KeyType key, EleType val) { if (key.CompareTo(patt) != 0 && !dd.ContainsKey(key)) dd.Add(key, val); } }
Dict dis = new Dict (); 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ładowaopis 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
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 (A arg); // Fun d1; // long FK (int x) { return (long)x L; } d1 = FK; // Fun d2; Fun d3;
● wyrażenia lambda (funkcje nienazwane) (3.0) - jeden argument delegate R Fun (A arg); // Fun L1 = x => x * x + 1; // λ x. x * x + 1 Console.WriteLine( L1(12) ); // 145 // Fun L2 = x => (double)x / ; // Console.WriteLine( L2(7) ) ; // 4,0
- wiele argumentów delegate R Arg2 (A x, B y); // Arg2 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 ( ) ; Console.WriteLine ( msg ); } Event
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); }}}
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 : 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
Linq to Objects -> Linq to own sources -> Linq1 Linq2
Współbieżność przestrzeń nazw System.Threading klasa Thread tworzenie ścieżek 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 ścieżek Lowest BelowNormal Normal AboveNormal Highest ścieżki pierwszoplanowe i drugoplanowe ( ForeGround / BackGroung Threads ) – dopóki istnieje przynajmniej jedna ścieżka pierwszoplanowa aplikacja nie jest zamykana przez CLR – po zakończeniu ostatniej ścieżki pierwszoplanowej CLR kończy wszystkie aktywne jeszcze ścieżki drugoplanowe
public class Worker { public bool EndOfWork = false ; public void DoWork ( ) // funkcja ścieżki { 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 ścieżki { 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 druga ścieżka // zakończyła 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, ta sama ścieżka int answer = b(10, 10); // lub int answer = b.Invoke(10, 10);
// asynchronicznie, odrębna ścieżka 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(" 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ł // ścieżka drugoplanowa 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; } } // ścieżki 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 } } // ścieżki 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 ścieżek CLR ─ powołanie nowej ścieżki ( async delegate ) powoduje uruchomienie jednej z oczekujących ścieżek utworzonych dla programu przez CLR ─ można do kolejnych ścieżek puli przypisywać funkcje do wykonania ( poprzez delegację WaitCallback ) - ścieżki drugoplanowe [Synchronization] public class Printer : ContextBoundObject { 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(); }
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 5 ścieżek, z których każda // wykonuje funkcję zawartą w delegacji DoWork DataPara
─ współbieżne obliczenia Parallel.Invoke( action [ ] ac_list) // powołanie dla każdej akcji z ac_list // ścieżki wykonującej tę akcję ─ przerwanie wykonania wszystkich ścieżek CancelationToken TaskPara
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 ); }
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 = ; public static readonly double e = ; 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 Manifest Metadane Typów CIL Zasoby
składniki przestrzeni nazw System.Reflection KlasaOpis 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 ctulg = a.GetType("CarTuneUpLib.Garage"); MemberInfo [ ] mi = ctulg.GetMembers( ); // podobnie parametry funkcji
dynamiczne wywoływanie funkcji // tworzenie klasy object obj = Activator.CreateInstance( ctulg ); // MethodInfo wash = ctulg.GetMethod( "WashCar" ); wash.Invoke( obj, null ); // bezargumentowa // object [ ] TabPar = { par1, par2,... }; xxx.Invoke ( obj, TabPar ); // z argumentami
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