1.67k likes | 1.84k Views
C#, Visual Studio 2010, .NET 4.0. dr inż. Marcin Radom Instytut Informatyki, Politechnika Poznańska laboratorium Programowania Wizualnego. Część I: Wstęp, C# i .NET. Tajemnicze skróty z .NET. CLR – Common Language Runtime CTS – Common Type System CLS – Common Language Specification
E N D
C#, Visual Studio 2010,.NET 4.0 dr inż. Marcin Radom Instytut Informatyki, Politechnika Poznańska laboratorium Programowania Wizualnego
Tajemnicze skróty z .NET • CLR – Common Language Runtime • CTS – CommonType System • CLS – Common Language Specification • JIT(ter) – Just-in-time Compiler • CIL – CommonIntermediate Language (przez JIT) • .NET Metadata • .NET Asembly Manifest
Użyteczne programy • ildasm.exe ( \Program Files\Microsoft SDKs\7.0A\bin\ ) • Reflector ( http://www.red-gate.com/products/reflector )
Kompilator konsolowy • csc.exe ( dostęp np. poprzez link w zainstalowanym folderze menu Start ) • Parametry:/out /target:exe (library, module, winexe) • C:\csc.exe /target:exe Program.cs C:\csc *.cs C:\csc /out:MojProgram.exe @Program.rsp
Pliki *.rsc • # External assembly references. /r:System.Windows.Forms.dll # Output and files to compile (using wildcard syntax). /target:exe /out:Program.exe *.cs • csc.rsp ( \Windows\Microsoft.NET\Framework\<version> )
Inne programy • Notepad++ http://notepad-plus.sourceforge.net • SharpDevelop http://www.sharpdevelop.com • Mono http://www.mono-project.com • Visual C#2010 Express
Cechy MS Visual Studio 2010 • Solution Explorer Utility • Referencing External Assemblies • Project Properties • Class View Utility • Object Browser Utility • Integrated Support for Code Refactoring • Code Expansion and Surround With Technology • Visual Class Designer
Hello World w C# usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; namespaceConsoleApplicationExemplar { classProgram { staticvoidMain(string[]args) { Console.WriteLine("Hello World!"); Console.WriteLine(); Console.ReadLine(); } } }
Przetwarzanie parametrów wejściowych • for(int i = 0; i < args.Length; i++) Console.WriteLine("Arg: {0}", args[i]); -wyświetli listę parametrów startowych • foreach(string arginargs) Console.WriteLine("Arg: {0}", arg); -jak wyżej • string[] theArgs = Environment.GetCommandLineArgs(); foreach(stringargintheArgs) Console.WriteLine("Arg: {0}", arg); -jak wyżej
Obiekty Environment, Console – i ich przydatne metody (do sprawdzenia we własnym zakresie) • Environment.OSVersion (ProcessorCount, Version) • Console.WriteLine (ReadLine, Beep(), BackgroundColor, BufferHeight, Width, Title, Clear, etc. ) • Console.WriteLine( „{0} oraz {0}”, 9 ); • {0:c} {0:d9} {0:f3} etc…
Zmienne • floatL1 = 7.4F; (bez F – double) longL2 = 10D; (bez D – int) • ponieważ liczby w C# to struktury, można wykonać operacje: • 12.GetHashCode(); //12 • 12.Equals(23); //FALSE • 12.ToString(); //12 • double.MaxValue • double.PositiveInfinity, etc…
BigInteger – na naprawdę duże liczby • System.Numerics (References->Add reference ->zakładka .NET ) static void UseBigInteger() { Console.WriteLine("Use BigInteger:"); BigInteger dlug = BigInteger.Parse(„10000000000000000000000000000000999"); Console.WriteLine("{0}", dlug); Console.WriteLine("{0}", dlug.IsEven); Console.WriteLine("{0}", dlug.IsPowerOfTwo); BigIntegerdlugUSA = BigInteger.Multiply(dlug, BigInteger.Parse("100000000000000000000000000000000"); Console.WriteLine("{0}", dlugUSA); }
Łańcuchy • String – czyli to co wszyscy znają • Łańcuchy dosłowne (verbatim) @ - wszystko wewnątrz jest traktowane jako łańcuch, nawet (a raczej: zwłaszcza) wszystkie znaki specjalne jak / \ ” itd. • StringBuilder (System.Text) - jeżeli chcemy oszczędzać pamięć
Rozszerzanie / zawężanie typów danych • implicit / explicit – sposób przypisywania zmiennych różnych typów – pierwszy to domyślny, nie działa przy przekraczaniu zakresu typu, drugi wprost mówi kompilatorowi, że wiemy co robimy, np. zmienna_int = (int)wielki_float; • checked / unchecked • Opcje domyślne dla środowiska w kwestiach powyższych: Properties -> Build -> [Advanced]Button
Zmienna typu zmienna, czyli typ ’var’ • varcos = 0; • cos.GetType().Name//wynik: int varmyInt = 0; varmyBool = true; varmyString = "Time, marches on..."; • Błędy: • publicvarcos = 0; • publicvarMetoda(varx); • varcos; cos=0; • varobiekt = null; • var? nic = nowyObiekt(); • var? blad = 12;
(Elementarne) konstrukcje języka Pętle: • foreach; for • while; do / while Instrukcje warunkowe: • if/ else • switch() { case1: …. break; case2: …. break default: …. break }
Parametry argumentów metod: out, ref, params • OUT – wywoływana metoda MUSI zwrócić wartość • REF – wywoływana metoda może trwale zmienić wartość • PARAMS – w skrócie(wielkim): nieokreślona liczba zmiennych pewnego typu public staticvoidSwapStrings(ref string s1, ref string s2) { string tempStr = s1; s1 = s2; s2 = tempStr; } staticvoidMain(string[] args) { Console.WriteLine("**********"); string s1 = "Flip"; string s2 = "Flop"; Console.WriteLine("Before: {0}, {1} ", s1, s2); SwapStrings(ref s1, ref s2); Console.WriteLine("After: {0}, {1} ", s1, s2); Console.ReadLine(); } • Before: Flip, Flop After: Flop, Flip
params static double Srednia(params double[]values) { Console.WriteLine(„Ile: {0}",values.Length); double sum= 0; if (values.Length== 0) return sum; for (int i= 0;i<values.Length;i++) sum +=values[i]; return (sum /values.Length); } double average; average = Srednia(4.0, 3.2, 5.7, 64.22, 87.2); Console.WriteLine("Average of data is: {0}", average); double[] data = { 4.0, 3.2, 5.7 }; average = Srednia(data); Console.WriteLine("Average of data is: {0}", average);
Parametry opcjonalne (.NET 4.0) static void EnterLogData(string message, string owner ="Programmer") { Console.Beep(); Console.WriteLine("Error: {0}", message); Console.WriteLine("Owner of Error: {0}", owner); } static void Main(string[] args) { EnterLogData(„ERROR"); EnterLogData(„ERROR", „Ja"); Console.ReadLine(); }
Wywoływanie metod z nazwanymi parametrami (.NET 4.0) • Kolejność wywołania: dowolna staticvoidMain(string[] args) { Metoda(message: "Test",textColor: ConsoleColor.DarkRed, BackgroundColor: ConsoleColor.White); Metoda(backgroundColor:ConsoleColor.Green, Message:"Testing...",textColor:ConsoleColor.DarkBlue); Console.ReadLine(); } staticvoidMetoda(ConsoleColortextColor,ConsoleColorbackgroundColor,string message) { ... }
Przeciążenie metod static int Add(int x, int y) { return x + y; } static double Add(double x, double y) { return x + y; } static long Add(long x, long y) { return x + y; } static void Main(string[] args) { Console.WriteLine(""); Console.WriteLine(Add(10, 10)); Console.WriteLine(Add(900000000000, 900000000000)); Console.WriteLine(Add(4.3, 4.4)); Console.ReadLine(); }
Tablice int[]myInts = new int[3]; myInts[0] = 100; myInts[1] = 200; myInts[2] = 300; string[]stringArray = new string[] {"raz","dwa","trzy"}; Console.WriteLine("Elementów: {0}", stringArray.Length); bool[] boolArray = { false, false, true }; Console.WriteLine("Elementów: {0}", boolArray.Length); int[]intArray = new int[4] { 20, 22, 23, 0 }; Console.WriteLine("Elementów: {0}", intArray.Length); Console.WriteLine();
Tablice typu varTablice obiektów Console.WriteLine("=> Implicit Array Initialization."); var a = new[] { 1, 10, 100, 1000 }; Console.WriteLine("a is a: {0}", a.ToString()); var b = new[] { 1, 1.5, 2, 2.5 }; Console.WriteLine("b is a: {0}", b.ToString()); var c = new[] { "hello",null,"world" }; Console.WriteLine("c is a: {0}", c.ToString()); Console.WriteLine(); object[]myObjects = new object[4]; myObjects[0] = 42; myObjects[1] = false; myObjects[2] = new DateTime(2012, 12, 22); myObjects[3] = "Form & Void"; foreach (object obj in myObjects) { Console.WriteLine("Type: {0}, Value: {1}", obj.GetType(),obj); }
Tablica postrzępiona(jaggedarray) staticvoidJaggedMultidimensionalArray() { int[][] myJagArray = newint[5][]; for (inti = 0; i < myJagArray.Length; i++) myJagArray[i] = newint[i + 7]; for (inti = 0; i < 5; i++) { for (intj = 0; j < myJagArray[i].Length; j++) Console.Write(myJagArray[i][j] + " "); Console.WriteLine(); } Console.WriteLine(); } 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Typy wyliczeniowe enumEmpType:byte { Manager = 10, Grunt = 1, Contractor = 100, VicePresident = 999 } staticvoidMain(string[] args) { EmpTypeemp= EmpType.Contractor; AskForBonus(emp); Console.ReadLine(); Console.WriteLine("empis a {0}.",emp.ToString()); // Wypisze "Contractor = 100". Console.WriteLine("{0} = {1}",emp.ToString(), (byte)emp); } static void AskForBonus(EmpType e) { switch (e) { case EmpType.Manager: Console.WriteLine(„A może akcje?"); break; case EmpType.Grunt: Console.WriteLine(„Bardzo zabawne..."); break; case EmpType.Contractor: Console.WriteLine(„Ty zdzierco..."); break; case EmpType.VicePresident: Console.WriteLine(„TAK JEST!”); break; } }
Struktury static void Main(string[] args) { Point myPoint; myPoint.X = 349; myPoint.Y = 76; myPoint.Display(); myPoint.Increment(); myPoint.Display(); Console.ReadLine(); } struct Point { public int X; public int Y; public void Increment() { X++; Y++; } public Point(int xP, int yP) { X = xP; Y = yP; } public void Display() { Console.WriteLine("X = {0}, Y = {1}", X, Y); } }
Inne sposoby pracy z typami (możliwe w C#) • Typy wartościowe zawierające typy referencyjne ( structzawierające class) • Przekazywanie typów referencyjnych przez wartość( publicvoidMetoda(Person p) { … } ) • Przekazywanie typów referencyjnych przez referencje( ref) • Wiele innych
Typy nullable, operator ?? int? nullableInt = 10; double? nullableDouble = 3.14; bool? nullableBool =null; char? nullableChar = 'a'; int?[]arrayOfNullableInts=newint?[10]; // compile-time error: string? s = "oops"; int?jakasLiczba = Metoda() ?? 100; // jeżeli Metoda() zwróci coś o wartości NULL, wtedy (i tylko wtedy) przypisz wartość 100 do ‘jakasLiczba’
Przykład klasy class Car { public string petName; public int currSpeed; public void PrintState() { Console.WriteLine ("{0} jedzie {1} kmh.", petName, currSpeed); } public void SpeedUp(int delta) { currSpeed += delta; } } class Program { static void Main(string[] args) { Car myCar =new Car(); myCar.petName = "Audi"; myCar.currSpeed = 10;for (int i = 0; i <= 10; i++) { myCar.SpeedUp(5); myCar.PrintState(); } Console.ReadLine(); } }
this public intcurrSpeed; public Car(intcurrSpeed) { currSpeed = currSpeed; } VS: public Car(intcurrSpeed) { this.currSpeed = currSpeed; }
this – wskazanie na konstruktor class Motorcycle { public int power; public string driverName; public Motorcycle() { } public Motorcycle(int intensity) : this(intensity, "") { } public Motorcycle(string name) : this(0, name) { } public Motorcycle(int pow, string name) { if(pow > 10) { pow = 10; } power = pow; driverName = name; } } • Motorcycle c = new Motorcycle(5); • najpierw wykona się najniższy konstruktor (czyli Motorcycle(int pow, string name) ), dopiero potem ten, który przyjmuje int (z powodu konstrukcji: " : this(intensity, ” ”) { } "
Konstruktor z domyślnymi parametrami (.NET 4.0) public Motorcycle(int power = 0, string name ="") { if (power > 10) { power = 10; } this.power = intensity; driverName = name; }
static class Motorcycle { public static int ileMotocykli; public static int liczbaStworzonychObiektow() { return ileMotocykli; } } • Dostępne z poziomu klasy, nie obiektu – wszystkie nowe obiekty współdzielą jedną wersję pól statycznych / metod statycznych w ramach swojej klasy. • Tylko metody statyczne i pola statyczne mogą być używane wewnątrz metod statycznych – nie mają one dostępu do zwykłych pól, bo te nie istnieją na tym poziomie (żadnego „this”! ).
Programowanie obiektowe (OOP) • Czyli co należy znać już od dawna: • dziedziczenie • polimorfizm • hermetyczność • używanie obiektów innej klasy w jeszcze innym obiekcie (jeszcze innej klasy), etc. • virtual • override • sealed • abstract
Modyfikatory dostępu • public • private( domyślny ) • protected • internal(domyślny ) • protectedinternal
Właściwości ( properties ) class Employee{ private string empName; private int empID; private float currPay; public string Name { get { return empName; } set { if (value.Length > 30)Console.WriteLine("Przekroczony limit znakow."); else empName = value; } }public int ID { get { return empID; } set { empID = value; } } public float Pay { get{ return currPay; } set { currPay = value; } } }
Właściwości (seq.) • modyfikatory dostępności: publicstring SSN { get { return empSSN; } protected set { empSSN = value; } } • tylko do odczytu: publicstring SSN { get { return empSSN; } } • automatyczne: class Car { public string PetName { get; set; } public int Speed { get; set; } public string Color { get; set; } }
Inicjalizator obiektów classPunkt { public intX { get; set; } public intY { get; set; } public Punkt(intxVal,intyVal) { X = xVal; Y = yVal; } public Punkt() { } public voidShowData() { Console.WriteLine("[{0}, {1}]", X, Y); } } Punkt finalPoint = newPunkt {X = 30, Y = 30 }; Punkt finalPoint2 = newPunkt(){ X = 30, Y = 30 }; Punkt pt = newPunkt(10, 16) { X = 100, Y = 100 }; //no i jakie teraz będą współrzędne? finalPoint.ShowData(); Console.ReadLine();
Inicjalizator obiektów (seq.) classPunkt { public intX { get; set; } public intY { get; set; } public PointColorColor { get; set; } public Punkt(intxVal,intyVal) { X = xVal; Y = yVal; } public Punkt() { } public Punkt(PointColorptColor) { Color = ptColor; } public Punkt() :this(PointColor.BloodRed){ } public voidShowData() { Console.WriteLine("[{0}, {1}]", X, Y); } } … Punkt goldPoint= newPunkt(PointColor.Gold){ X = 90, Y = 20 };
Stałe • const public const double Pi = 3.14; const string napis ="NAPIS"; • readonly public readonly double PI; … public Klasa() { PI = 3.14; } • także: static dodane do powyższych - o ile potrzebujemy stałych statycznych (np. aby móc na nich operować wewnątrz metod statycznych).
Dziedziczenie classSamochod { public readonlyintlimit; privateintcurrSpeed; public Samochod(intmax) { limit = max; } public Samochod() { limit = 55; } public intSpeed { get{ return currSpeed; } set { currSpeed = value; if(currSpeed > limit) { currSpeed = limit; } } } } classCiezarowka:Samochod { }
Dziedziczenie (seq.) • Brak wielokrotnego dziedziczenia klas (działa dla interfejsów) • SEALED – zamknięcie dalszego dziedziczenia z klasy, którą poprzedzimy właśnie rozkazem ‘sealed’ • Załóżmy, że klasa nadrzędna ma 5 pól publicarg1 - arg5, dziedzicząca dodała własne arg6, wtedy konstruktor dziedziczącej, żeby się nie powtarzać może wyglądać tak: public Dziedziczaca(int arg1, int arg2, int arg3, string arg4, string arg5, double arg6) : base (arg1, arg2, arg3, arg4, arg5) { pole6 = arg6; }
Typy zagnieżdżone classZewnetrzna { public classWewnetrzna{ } privateclassJeszczeJednaWewnetrzna{ } } • Cechy: • Kontrola takiej klasy (zagnieżdżonej) • dostęp do private • typ pomocniczy
Polimorfizm: virtual, override, etc. classPrzyklad { privateintdane = 1; public virtualvoidStats() { Console.WriteLine(dane); } } classInna :Przyklad { privateintinneDane = 10; public overridevoidStats() { Console.WriteLine(inneDane); } } • Bez słów virtual/override– wystąpi ostrzeżenia środowiska i kompilatora, ale tylko ostrzerzenie (program wciąż można kompilować). Można użyć słówka ‘new’ jako słowa środowiskowego: „odczep się, wiem co robię” – jest to tzw. cieniowanie składowych. • public overridesealedvoidStats () { … }