Podstawy C#

71
Nowa wersja C# Autor: Piotr Sobczak Seminarium magisterskie „Zagadnienia programowania obiektowego” Wydział Matematyki, Informatyki i Mechaniki Uniwersytet Warszawski

Transcript of Podstawy C#

Page 1: Podstawy C#

Nowa wersja C#

Autor: Piotr Sobczak

Seminarium magisterskie „Zagadnienia programowania obiektowego”Wydział Matematyki, Informatyki i MechanikiUniwersytet Warszawski

Page 2: Podstawy C#

PLAN- podstawy: Wprowadzenie Przestrzenie nazw Typy, parametry, konwersje Klasy Instrukcje sterujące Właściwości Interfejsy, operatory is i as Wyjątki Delegaty

Page 3: Podstawy C#

PLAN – rozszerzenia w C# 2.0:

Typ generyczny Metody anonimowe Typ dzielony Typ „nullable” Podsumowanie i wnioski

Page 4: Podstawy C#

Wprowadzenie

Język zorientowany-obiektowo, powstały na bazie C++ i Java

Pierwszy język programowania komponentowego z rodziny C/C++

Obsługuje: klasy, interfejsy, struktury Główny architekt – Anders Hejlsberg

Page 5: Podstawy C#

Klasy Definicja klasy jest połączona z deklaracją –

nie ma osobnych plików .h/.cpp, jak w przypadku C++

Przykład:public class HelloWorld

{

public static void Main()

{

System.Console.WriteLine(”Witamy w .NET”);

}

}

Page 6: Podstawy C#

Klasy – modyfikatory dostępu

Modyfikatory występują przed deklaracjami klas, metod, atrybutów.

public brak ograniczeń private dostęp tylko z wewnątrz klasy protected dostęp z wewnątrz klasy oraz z klas

dziedziczących internal dostęp z klas z tego samego pakietu protected internal = protected OR internal

Page 7: Podstawy C#

Klasy z atrybutem sealed

Jeżeli deklaracja klasy zawiera atrybut sealed, to nie jest możliwe jej dziedziczenie

sealed public class MojaKlasa{}

Page 8: Podstawy C#

Tworzenie obiektów

Tak samo jak w C++

Button b = new Button();

Page 9: Podstawy C#

Klasa object Wszystkie klasy dziedziczą po object

Zamiana na object może być niejawna, lecz w drugą stronę wymagane jest jawne rzutowanie

int i = 10;object obj = i;

int j = (int) obj;

Page 10: Podstawy C#

Konwersje między typami

niejawne (dopuszczalne, gdy nie ma straty)short x = 5;int y = x; // int ma 32bity, a short 16, wiec ok.

jawne (wymagane przy możliwości straty)int x = 500;short y = (short) x; // bez wymuszenia się nie skompiluje

Page 11: Podstawy C#

Przestrzenie nazw (namespaces)

Zapobiegają występowaniu konfliktów w nazwach klas

Grupują klasy o podobnym zastosowaniu Separatorem jest ‘.’ (znak kropki)

System.Console.WriteLine(”Tralalala”);System.Windows.Forms.Button b = new

System.Windows.Forms.Button();

Page 12: Podstawy C#

namespace - deklarowanienamespace Nazwa{

namespace NazwaWewnetrzna{

class PrzykladowaKlasa{

…}

}}

Odwołanie z zewnątrz:Nazwa.NazwaWewnetrzna.PrzykladowaKlasa

Page 13: Podstawy C#

Słowo kluczowe using

using System;

Console.WriteLine(”Witamy w .NET”);

using System.Console;

WriteLine(”Witamy .NET”);

UWAGA! Po UWAGA! Po using using nie podajemy nazwy klasy, tylko namespacenie podajemy nazwy klasy, tylko namespace

Page 14: Podstawy C#

System typów

Wspólny system typów (Common Type System)

Typy użytkownikaTyp wyliczeniowyStruktury

Page 15: Podstawy C#

Typy proste i typy referencyjne Typy proste

Pamiętają bezpośrednio dane

Każdy zawiera oddzielną kopię danych

Operacje na jednej zmiennej nie mają wpływu na inne

Typy referencyjne

Pamiętają referencję na pamiętane dane

Dwie zmienne mogą wskazywać na tą samą daną

Operacje na jednej zmiennej mogą mieć wpływ na inne

Page 16: Podstawy C#

Typy proste wbudowane

8-bitowe: byte, char, sbyte16-bitowe: short, ushort32-bitowe: int, uint, float64-bitowe:double, decimal, long, ulong

int liczba == System.Int32 liczbalong liczba == System.Int64 liczba

Page 17: Podstawy C#

Tworzenie typów użytkownika

Typ wyliczeniowydefiniowanie enum Kolor{Czerwony,Zielony,Niebieski};

sposób użyciaKolor kolor1 = Kolor.Czerwony;

Page 18: Podstawy C#

Tworzenie typów użytkownika cd.. Struktury

definiowanie struct Osoba

{ public string Imie, Nazwisko; public int Wiek; }sposób użycia Osoba pracownik;

pracownik.Imie = "Jan";pracownik.Wiek = 30;

Page 19: Podstawy C#

Przekazywanie parametrów 1/2

Przez wartość przekazywane są przedstawione typy wbudowane oraz:

enum, struct

Pozostałe typy przekazywane są przez referencję.

Page 20: Podstawy C#

Przekazywanie parametrów (2/2)

Typ podstawowy można przekazywać przez referencję wykorzystując słówko pomocnicze ref

public void Inkrementuj(ref int liczba){

liczba++;}

W wywołaniu metody także używamy ref:Inkrementuj(ref liczba);

Page 21: Podstawy C#

DziedziczeniePrzykład: class rodzic { virtual public void dajkasę() {...} } class dziecko: rodzic { override public void dajkasę() {...} } NIE jest dopuszczalne dziedziczenie wielokrotne Rozwiązanie poprzez implementację

Interfejsów

Page 22: Podstawy C#

if…else

Identyczna składnia, jak w C++ / Java

Warunek musi być typu bool (nie może być int, jak w C++)

Unikamy więc błędów typu:if (zmienna = 5)

Page 23: Podstawy C#

switch (1/2)

Nie jest dopuszczalny automatyczny przeskok do kolejnego przypadku

case 0:ZrobCos();break;

case 1:

poza sytuacją, gdy case jest „pusty”case 0:case 1:

ZrobCos();

Bez tego program się nie skompiluje

Page 24: Podstawy C#

switch (2/2) Skok do innego przypadku musi być jawny

case 0:ZrobCos();goto case 1;

case 1:

Wyrażenie może być string-iem (w C++ wymagany był int)

switch (nazwisko){

case „Kowalski”:ZrobCos();break;

case „Nowak”:ZrobCosInnego();break;

}

Page 25: Podstawy C#

while, do…while

while (i < 10){

Console.WriteLine(„Wartość {0}”, i);}

do{

Console.WriteLine(„Wartość {0}”, i);} while (i < 10);

Page 26: Podstawy C#

for – zakres zmiennych

Zmienne zadeklarowane w pętli for obowiązują jedynie wewnątrz pętli (tak jak w Javie; w C++ zależało to od wersji języka)

for (int i = 0; i < 10; i++){

…}for (int i = 5; i < 20; i++){

…}

Page 27: Podstawy C#

Foreachforeach (string nazwa in wszystkieNazwy)

{

Console.WriteLine(nazwa);

}

Wymagane: wszystkieNazwy musi realizować interfejs IEnumerable

Page 28: Podstawy C#

Tablice a „params” Pozwala tworzyć metody z nieokreśloną liczbą argumentów

public int Sumuj(params int[] skladniki){

int suma = 0;foreach (int skladnik in skladniki){

suma += skladnik;}return suma;

}

Sumuj (1, 2, 3, 4); == 10Sumuj (5, 6); == 11Sumuj (); == 0

Page 29: Podstawy C#

Właściwości/własności Class Test Użycie:{ Test pom=new

Test(); private int liczba; int x =pom.Liczba; public int Liczba pom.Liczba=1; {

get{return liczba;}set{liczba = value;if (liczba < 0) liczba = 0;}

}}

Page 30: Podstawy C#

Implementacja interfejsówinterface ITestable{

bool TestMe();}

public class MojaKlasa : ITestable{

bool TestMe(){

…}

}

Page 31: Podstawy C#

Operator IS is is służy do sprawdzenia, czy obiekt można rzutować na wybrany służy do sprawdzenia, czy obiekt można rzutować na wybrany

typ bez rzucania wyjątkówtyp bez rzucania wyjątków

objectobject obiekt = obiekt = newnew MojaKlasa(); MojaKlasa();

ifif (obiekt (obiekt isis MojaKlasa) MojaKlasa){{

((MojaKlasa)obiekt).Zagraj();((MojaKlasa)obiekt).Zagraj();}}

Możemy też sprawdzać, czy obiekt implementuje wybrany interfejs:Możemy też sprawdzać, czy obiekt implementuje wybrany interfejs:

ifif (obiekt (obiekt isis ITestable) ITestable)

Page 32: Podstawy C#

Operator as Łączy is z operatorem rzutowania. Jeśli rzutowanie

nie jest możliwe, zwraca null

protected void clicked(object sender, EventArgs e){

Button b = sender as Button;if (b != null){b.Text = „Naciśnięto”;}

}

Page 33: Podstawy C#

Kolekcje

ArrayList tablica Queue kolejka Stack stos Dictionarystruktura słownikowa

(łączy klucz-wartość) Hashtable tablica haszująca

Page 34: Podstawy C#

Wyjątki (1/3)try{

…}catch (IOException exception){

…}catch (Exception exception){

…}finally{

…}

Page 35: Podstawy C#

Wyjątki (2/3) Dopuszczalne jest użycie samego catchtry{

…}catch {

…} throw: słowo kluczowe umożliwiające zgłoszenie

wyjątku

Page 36: Podstawy C#

Wyjątki (3/3) Wymagana jest odpowiednia kolejność catchtry{

…}catch (Exception exception){

…}catch (IOException ioexception){

// tutaj nigdy nie dojdziemy, bo IOException jest // specjalizacją Exception, więc poprzedni catch // wyłapie ewentualny wyjątek

}

Page 37: Podstawy C#

Odpowiedniki wskaźników do funkcji z C++Odpowiedniki wskaźników do funkcji z C++

publicpublic delegatedelegate intint KtoryMniejszy ( KtoryMniejszy (objectobject o1, o1, objectobject o2); o2);

KtoryMniejszyKtoryMniejszy Porownanie Porownanie +=+= newnew KtoryMniejszy KtoryMniejszy (FunkcjaPorownawcza);(FunkcjaPorownawcza);

publicpublic intint FunkcjaPorownawcza ( FunkcjaPorownawcza (objectobject o1, o1, objectobject o2) o2){{

returnreturn (o1>o2); (o1>o2);}}

Tab.sort(Porownanie);Tab.sort(Porownanie);

Delegaty

Page 38: Podstawy C#

Delegaty i zdarzenia Delegaty są wykorzystywane do obsługi

zdarzeń

delegate void EventHandler (object sender, EventArgs e);

button1.Click += new EventHandler (KliknietoNaPrzycisku);

void KliknietoNaPrzycisku (object sender, EventArgs e){

Button nadawca = sender as Button;…

}

Page 39: Podstawy C#

GENERICS

Generics pozwala klasom, strukturom, interfejsom, delegatom i metodom być sparametryzowanym przez typ który przechowują i manipulują nim.

Jest podobny do generics w jezyku Eiffel ,Ada lub szablonów w C++.

Page 40: Podstawy C#

Dlaczego GENERICS?

public class Stack{object[] items;int count; public void Push(object item) {...} public object Pop() {...}}

Stack stack = new Stack(); stack.Push(new Customer()); Customer c = (Customer)stack.Pop();

Page 41: Podstawy C#

Generics

public class Stack<T> {

T[] items; int count;

public void Push(T item) {...} public T Pop() {...} }

Stack<int> stack = new Stack<int>();stack.Push(3);int x = stack.Pop();

Page 42: Podstawy C#

Generics- liczba paramerówpublic class Dictionary<K,V>

{public void Add(K key, V value) {...}

public V this[K key] {...}}

Dictionary<string,Customer> dict new Dictionary<string,Customer>();

dict.Add("Peter", new Customer()); Customer c = dict["Peter"];

Page 43: Podstawy C#

Generics - aliasy

using List = LinkedList<int,string>;

class ListClient{ static void Main(string[]args) { List list = new List(); list.AddHead(123,"AAA"); } }

Page 44: Podstawy C#

Generics - kompilacja

Kompiluje się do IL (instrukcje i metadane) Proces tworzenia – generic type instantion Po jednej instancji dla każdego typu

prostego Jedna instancja dla typów referencyjnych

Page 45: Podstawy C#

Generics – nie tylko dane 1/2 Nie tylko przechowywanie danych typu generycznego

public class Dictionary<K,V>{ public void Add(K key, V value) {

... if (key.CompareTo(x) < 0) {...} // Error, no ... }}

Page 46: Podstawy C#

Generics – nie tylko dane 2/2 Rozwiązanie za pomocą rzutowania:

public class Dictionary<K,V>{public void Add(K key, V value){... if (((IComparable)key).CompareTo(x) <0) {...}...}}

Page 47: Podstawy C#

Generics – Constraints 1/2 Czyli ograniczenia na parametry:

public class Dictionary<K,V> where K: IComparable{public void Add(K key, V value){...

if (key.CompareTo(x) < 0) {...}...}}

Page 48: Podstawy C#

Generics – Constraints 2/2 Ograniczenia mogą dotyczyć wielu Interfejsów,

1 klasy, a także konstruktora new().

public class EntityTable<K,E> where K: IComparable<K>, IPersistable

where E: Entity, new(){

public void Add(K key, E entity){

... if (key.CompareTo(x) < 0) {...}

...}

}

Page 49: Podstawy C#

Metody Generyczne 1/2

Możemy sparametryzować także metody.void PushMultiple<T> (Stack<T> stack, params T[] values) {

foreach (T value in values) stack.Push(value);}

Stack<int> stack = new Stack<int>();PushMultiple<int>(stack, 1, 2, 3, 4);

Page 50: Podstawy C#

Metody Generyczne 2/2 type inferencing – wywołanie metody z odpowiednim

typem generycznym na podstawie parametrów. Stack<int> stack = new Stack<int>();

PushMultiple(stack, 1, 2, 3, 4);

tak jak dla klas możemy wprowadzać też ograniczenia dla metod:

public class MyClass{ public void SomeMethod<T>(T t)

where T :IComparable<T> {...}}

Page 51: Podstawy C#

Typ generyczny i rzutowanie 1/3 Niejawnie możemy rzutować do object i do

typów występujących w ograniczeniach: class MyClass<T> where T : BaseClass,ISomeInterface { void SomeMethod(T t) { ISomeInterface obj1 = t; BaseClass obj2 = t; object obj3 = t; }

}

Page 52: Podstawy C#

Typ generyczny i rzutowanie 2/3 Jawnie rzutować możemy tylko do

interfejsów:

class MyClass<T> { void SomeMethod(T t) { ISomeInterface obj1 = (ISomeInterface)t; //Compiles

SomeClass obj2 = (SomeClass)t; //Does not compile }

}

Page 53: Podstawy C#

Typ generyczny i rzutowanie 3/3 Możemy ominąć to ograniczenie używając

zmiennej pomocniczej typu object: class MyClass<T> { void SomeMethod(T t) { object temp = t; SomeClass obj = (SomeClass)temp; } }

Warto używać operatorów is i as.

Page 54: Podstawy C#

Dziedziczenie i generics 1/2 Jeżeli klasa dziedziczy z klasy generycznej to musi być

podany konkretny typ jako parametr:

public class BaseClass<T>{...} public class SubClass : BaseClass<int>{...}

Chyba że klasa i podklasa są sparametryzowane tym samym parametrem:

public class SubClass<T> : BaseClass<T> {...}

Page 55: Podstawy C#

Dziedziczenie i generics 2/2 Przy dziedziczeniu należy powtarzać

ograniczenia w podklasach:public class BaseClass<T> where T : ISomeInterface {...}public class SubClass<T> : BaseClass<T> where T : ISomeInterface{...}

To samo dotyczy metod wirtualnych:public class BaseClass{

public virtual void SomeMethod<T>(T t) where T : new() {...}}public class SubClass : BaseClass{

public override void SomeMethod<T>(T t) where T : new() {...}

}

Page 56: Podstawy C#

Generics i delegaty Tak jak klasy struktury i interfejsy

możemy sparametryzować typem generycznym także delegaty:

public delegate void GenericDelegate<T>(T t); public class MyClass{ public void SomeMethod(int number) {...}}MyClass obj = new MyClass();GenericDelegate<int> del; del = new GenericDelegate<int>(obj.SomeMethod);

del(3);

Page 57: Podstawy C#

Kolekcje Generyczne

System.Collections.Generics i odpowiedniki System.Collections

Comparer<T> ComparerDictionary<K,T> HashTableList<T> ArrayListQueue<T> QueueSortedDictionary<K,T> SortedListStack<T> StackIComparable<T> IComparable

Page 58: Podstawy C#

Metody anonimowe 1/3 Zdarzenia są obsługiwane przez metody na które

wskazują delegaty. class InputForm: Form

{ListBox listBox;TextBox textBox;Button addButton;

public MyForm() {listBox = new ListBox(...);textBox = new TextBox(...);addButton = new Button(...);

addButton.Click += new EventHandler(AddClick);

} void AddClick(object sender, EventArgs e) {

listBox.Items.Add(textBox.Text);}

}

Page 59: Podstawy C#

Metody anonimowe 2/3 Ten sam przykład z użyciem metody anonimowej: class InputForm: Form

{ListBox listBox;TextBox textBox;Button addButton;

public MyForm() {listBox = new ListBox(...);textBox = new TextBox(...);addButton = new Button(...);

addButton.Click += delegate {listBox.Items.Add(textBox.Text);

}; }

}

Page 60: Podstawy C#

Metody anonimowe 3/3 Możemy także używać metod anonimowych do

wpisywania funkcji “in-line” delegate double Function (double x);class Test

{static double[] Apply(double[] a, Function f) { … }

static double[] MultiplyAllBy(double[] a, double factor) {

return Apply(a, delegate(double x) { return x * factor; });

} static void Main() {

double[] a = {0.0, 0.5, 1.0}; double[] squares = Apply(a, delegate(double x) { return x * x; });

double[] doubles = MultiplyAllBy(a, 2.0);}

}

Page 61: Podstawy C#

Iteratory 1/3

Żeby można było użyć pętli foreach na kolekcji, to kolekcja musi spełniać warunki:

Kolekcja musi implementować interfejs IEnumrable.

Kolekcja musi mieć bezparametrową metodę GetEnumerator.

Page 62: Podstawy C#

Iteratory 2/3 „Numeratory” są trudne do zaimplementowania. Sprawę ułatwiają nam ITERATORY: public class Stack<T>: IEnumerable<T>

{T[] items;int count;

public void Push(T data) {...} public T Pop() {...} public IEnumerator<T> GetEnumerator()

{for (int i = count – 1; i >= 0; --i) {

yield return items[i];}

}}

Mamy też do dyspozycji instrukcję yield break

Page 63: Podstawy C#

Iteratory 3/3 Możemy także zdefiniować kilka iteratorów dla 1

kolekcji:public class Stack<T>: IEnumerable<T>

{…

public IEnumerator<T> GetEnumerator() {for (int i = count – 1; i >= 0; --i) {yield return items[i];}} public IEnumerable<T> TopToBottom {get {return this; }}

public IEnumerable<T> BottomToTop {get {for (int i = 0; i < count; i++) {yield return items[i];} }}}

Page 64: Podstawy C#

Iteratory 3/3 cd..Użycie: class Test

{static void Main()

{ Stack<int> stack = new Stack<int>(); for (int i = 0; i < 10; i++) stack.Push(i);

foreach (int i in stack.TopToBottom) Console.Write("{0} ", i);

foreach (int i in stack.BottomToTop) Console.Write("{0} ", i);

}}

Page 65: Podstawy C#

Partial types 1/2 Podział zawartości 1 klasy w więcej niż jednym pliku np:

plik1.cs public partial class Customer

{private int id;private string name;private string address;private List<Order> orders;

public Customer() {...

} }

Page 66: Podstawy C#

Partial types 2/2 Plik2.cs public partial class Customer

{public void SubmitOrder(Order order) {

orders.Add(order);}

public bool HasOutstandingOrders() {return orders.Count > 0;

}}

Page 67: Podstawy C#

Nullable type 1/3

Wprowadza dla wszystkich typów prostych wartość null.

int? Jest to typ wbudowany + wartość null. HasValue - właściwość, która zwraca nam

true or false jeżeli typ jest nullable lub nie.

Page 68: Podstawy C#

Nullable type 2/3

Operacje arytmetyczne z null-em dają null Operatory >,<,<=, >= zwracają false jeżeli

któryś z argumentów jest null. Nowy operator ??. a??b – rezultatem jest a jeżeli a jest

not-null i b w przeciwnym przypadku.

Page 69: Podstawy C#

Nullable type 3/3 Przykład: int? x = GetNullableInt();

int? y = GetNullableInt();int? z = x ?? y;int i = z ?? -1;

Operator ten działa też dla typów referencyjnych:

string s = GetStringValue();Console.WriteLine(s ?? "Unspecified");

Page 70: Podstawy C#

PODSUMOWANIE

Została zachowana maksymalna zgodność wstecz.

Jeszcze większy wachlarz konstrukcji. Ciągle najlepszy język do programowania

na platformie .NET

Page 71: Podstawy C#

Koniec.Dziękuję za uwagę.