Język C# ( 4.0 ) using System; namespace HeWo { class Hello {
-
Upload
maile-payne -
Category
Documents
-
view
35 -
download
0
description
Transcript of Język C# ( 4.0 ) using System; namespace HeWo { class Hello {
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 1 falsebyte Byte Y 1 0sbyte SByte N 1 0short Int16 Y 2 0int Int32 Y 4 0long Int64 Y 8 0ushort UInt16 N 2 0uint UInt32 N 4 0ulong UInt64 N 8 0float Single Y 4 0.0double Double Y 8 0.0 char Char Y 2 0decimal Decimal Y 16 0.0
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 = 3.857 ;
Typy implikowane (3.0)
var a = 5; // intvar b = 'K'; // charvar c = 128L; // longvar d = 15.332; // double var e = "Ala ma kota"; // string a = 4654434L; // long -> inte = 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 ;
//
string str = null;
/* . . . . . . . . */
Console.WriteLine( str ?? "Pusty" );
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, // == 1Fake = 10, // == 10Drake // == 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
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ń
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
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 bezG g
N n format narodowy
X x postać heksydecymalna
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.IComparable< T >
{ T pom;
if ( p1.CompareTo( p2 ) < 0 )
pom = p1;
else
pom = p2;
return pom;
}
// p1 < p2 błąd
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 ) // poprawnieNamedPar, Refa
Klasy
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 ;
}
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)
modyfikator 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 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
// protectedDrawRect
● 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 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 + 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 " ;
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();
elsekli = 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ówpublic 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!
Dziedziczeniepublic 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 );
}
}
Finalizacjapublic 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
BinaryWriter
StreamReader
StringReader
StreamWriter
StringWriter
TextWriter TextReaderWrite ( ) Peek ( )
WriteLine ( ) Read ( )
Flush ( ) ReadLine ( )
Close ( ) ReadToEnd ( )
podstawowe funkcje
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 ( ) ;
// albo
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();
klasy BinaryReader BinaryWriter
BinaryRW
BinaryWriter BinaryReaderWrite ( ) PeekChar ( )
Seek ( ) Read ( )
Flush ( ) ReadXXX ( )
Close ( ) 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
// <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
Count // właściwość
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
Wzorce klas kolekcji
generics, typy parametryczne, typy uogólnione
Dictionary <key, value>
SortedDictionary <key, value>
LinkedList <type> // dwukierunkowa
List <type> // jednokierunkowa
SortedList <key, value>
Queue <type>
Stack <type>
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 { .... }
} }
- 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
Targetnazwa 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;
● 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 ( ) ;
Console.WriteLine ( msg );
}
} 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); }}}
• 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
• 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("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ł
// ś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
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 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 integerstry{ 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 ;
public static readonly double
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
Manifest
Metadane Typów
CIL
Zasoby
.......
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 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