Kurssin yleiset asiat, C#-perusteet - luento 1
- Luentotaltiointi
- Yleiset asiat
- C#
- .NET Framework
- Common Language Infrastructure (CLI)
- Hello World
- Tietotyypit
- Varattuja sanoja
- Ehtolauseet ja silmukat
- Taulukot
- Merkkijonot
- C#-kielen ominaisuuksia
- Luokat
- ref, out ja params
- Properties
- Indeksoija
- enum
- Struct vs Class / arvotyypit vs referenssityypit
- Poikkeukset
- Debuggaus
- Avustus
- Lisätietoa
Luentotaltiointi
Ongelmia videon katselussa?Luennolla käsitellään erittäin lyhyesti perusteita c#-kielestä.
Yleiset asiat
C#
C# (lausutaan: C sharp) on Microsoftin kehittämä olio-ohjelmointikieli
C# on ECMA-organisaation standardoima kieli
C# on tulkattu kieli
Muistuttaa syntaksiltaan C++- ja Java-kieliä.
Kaikki muuttujat ovat tyypitettyjä
Isoilla ja pienillä kirjaimilla on merkitystä
C#:ssa on pelkästään olioita
Automaattinen roskien keruu (Garbage collection)
Kaikki muuttujat pitää alustaa ennen käyttöä
Tukee osoittimia (unsafe)
Tukee ominaisuuksia (properties), indeksoijia, delegaatteja, tapahtumia, muuttujien välitystä viitteinä
Nimeämiskäytäntö: Sama kuin Pascal-kielessä eli kaikkien sanojen ensimmäiset kirjaimet kirjoitetaan kapiteeleilla.
.NET Framework
- .NET Framework on Microsoftin kehittämä ohjelmistokomponenttikirjasto
- Toimii vain Windows-ympäristöissä. Tulevaisuudessa voi toimia muuallakin.
- C# käyttää .NET-kirjastoa
- .NET pitäisi olla kielineutraali. Sopivan kielen pitää tukea Common Type Systemiä (CTS). Lisäksi CTS:n osajoukko nimeltään Common Language Specification (CLS) määrää miten tehdään komponentit joiden halutaan toimivan kieliriippumattomasti.
- Base Class Library
- Framework Class Library (FCL
Common Language Infrastructure (CLI)
Common Language Infrastructure on ympäristö jossa voidaan suorittaa korkean tason ohjelmointikielillä tehtyjä ohjelmia erilaisissa tietokoneympäristöissä. CLI on käytännössä ECMA-standardi, joka määrittelee .NET-rajapinnan. CLIn toteutuksia ovat mm. Microsoftin Rotor, Mono ja Portable .NET
Common Language Runtime (CLR)
- CLR on Microsoftin toteutus CLI-ympäristöstä
- CLR suorittaa kunkin ohjelman omassa hiekkalaatikossaan
- CLR-ympäristössä ohjelmat ovat Common Intermediate Language (CIL) -muodossa
- Ohjelman suorituksen aikana CIL-muotoinen ohjelma käännetään (Just-in-time) ajoympäristössä toimivaan muotoon
Hello World
using System; // using on vastaava kuin Javan import // "Hello World!" -ohjelma C#-kielellä namespace HelloWorld // namespace on vastaava kuin Javan package { /// Tämä on dokumentaatiokommentti (vrt. javadoc) class Hello { static void Main() { Console.WriteLine("Hello World!"); // System.Console.ReadKey(); } } /* myös monen rivin kommentit toimivat */ }
- Ohjelman suoritus alkaa luokan Main-metodista
- Main-metodi voi palauttaa void tai int
- Main-metodin parametreina voidaan lukea komentoriviargumentit:
static void Main(string[] args)
- Kooditiedoston nimellä tai sen sisältämien luokkien muodolla tahi määrällä ei ole rajoituksia
- Jos tiedostossa on useampia luokkia joilla on Main-metodi niin käynnistyessä suoritettava Main pitää määrätä käännösaikana
Tietotyypit
- bool
- char
- sbyte etumerkillinen, 8-bit
- byte etumerkitön, 8-bit
- short etumerkillinen, 16-bit
- ushort etumerkitön, 16-bit
- int
- uint
- long
- ulong
- float
- double
- decimal 128-bittinen desimaaliluku 28 merkitsevällä numerolla
- true
- false
- null
- void
Varattuja sanoja
Seuraavassa on lueteltu joitakin Javasta poikkeavia c#-kielen käyttämiä sanoja. Näiden käyttämiseen palataan myöhemmin kurssin aikana.
- delegate
- enum
- event
- this
- operator
- struct
- params
- out
- ref
- as
- is sama kuin Javan instanceof
- typeof
- base sama kuin javan super
- explicit
- implicit
- fixed
- sizeof
- stackalloc
- unsafe
Varattuja sanojakin voidaan käyttää metodien ja muuttujien niminä jos niihin laitetaan etuliitteeksi @.
Ehtolauseet ja silmukat
Ehtolauseet ja silmukat toimivat hyvin samaan tapaan kuin Javassa. Lisäyksenä kuitenkin foreach-silmukka ja goto-käsky.
foreach (int apu in array3) { Console.WriteLine(apu); }
Taulukot
- Taulukko voi olla yksi- tai moniulotteinen.
- Numeeriset taulukot alustetaan automaattisesti nollaksi ja referenssitaulukot nulliksi
- Taulukon indeksit alkavat nollasta
class TestArraysClass { static void Main() { // Declare a single-dimensional array int[] array1 = new int[5]; // Declare and set array element values int[] array2 = new int[] { 1, 3, 5, 7, 9 }; // Alternative syntax int[] array3 = { 1, 2, 3, 4, 5, 6 }; // Declare a two dimensional array int[,] multiDimensionalArray1 = new int[2, 3]; // Declare and set array element values int[,] multiDimensionalArray2 = { { 1, 2, 3 }, { 4, 5, 6 } }; // Declare a jagged array int[][] jaggedArray = new int[6][]; // Set the values of the first array in the jagged array structure jaggedArray[0] = new int[4] { 1, 2, 3, 4 }; } }
Merkkijonot
- Valmiita merkkijonoja ei voi muuttaa
string s = "Hello, World!"; string hello = "Hello\nWorld!"; string filePath = "\\\\My Documents\\"; string p2 = @"\\My Documents\My Files\"; int year = 1999; string msg = "Eve was born in " + year.ToString(); string s4 = "Hello, World"; char[] arr = s4.ToCharArray(0, s4.Length); System.Console.Write(s4[3]);
C#-kielen ominaisuuksia
int myInt = 5; if (myInt < 0) // ehdon pitää palauttaa true tai false. Console.WriteLine("Your number {0} is less than zero.", myInt); else Console.WriteLine("Your number {0} is more than zero.", myInt); switch (myInt) { case 0: Console.WriteLine("Your number is {0}.", myInt); break; case 1: Console.WriteLine("Your number is {0}.", myInt); break; case 2: Console.WriteLine("Your number is {0}.", myInt); break; default: Console.WriteLine("Your number {0} is not between 0 and 2.", myInt); break; }
Luokat
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace hello { class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); // Alternative syntax int[] array3 = { 1, 2, 3, 4, 5, 6 }; foreach (int apu in array3) { Console.WriteLine(apu); } Henkilo tommi = new Henkilo("Tommi", "Lahtonen"); tommi.Tulosta(); Duunari antti = new Duunari("Antti", "Ekonoja", "yliopistonopettaja"); antti.Tulosta(); Henkilo[] taulukko = { tommi, antti }; Console.WriteLine("--------------------------"); foreach (Henkilo p in taulukko) { p.Tulosta(); } Console.WriteLine("--------------------------"); antti.ika = -5; antti.Tulosta(); antti.ika = 25; antti.Tulosta(); Console.ReadKey(); } } } public class Henkilo { protected string etunimi; protected string sukunimi; public Henkilo() { etunimi = "Matti"; sukunimi = "Meikäläinen"; } public Henkilo(string etu, string suku) { etunimi = etu; sukunimi = suku; } // entäs virtual // public virtual void Tulosta() public void Tulosta() { Console.WriteLine(this.etunimi); Console.WriteLine(this.sukunimi); } ~Henkilo() { Console.WriteLine(this.etunimi + " " + this.sukunimi + " dies"); } } public class Duunari : Henkilo { private string tehtava; public Duunari(string etu, string suku, string tehtava) // public Duunari(string etu, string suku, string tehtava) // : base(etu, suku) { this.etunimi = etu; this.sukunimi = suku; this.tehtava = tehtava; } // mitäs jos new korvataan sanalla override? // public override void Tulosta() public new void Tulosta() { // base.Tulosta(); Console.WriteLine(this.tehtava); Console.WriteLine(ika); } private int m_ika = 20; public int ika { get { return m_ika; } set { if (value > 0) m_ika = value; } } }
ref, out ja params
using System; class Testi { public static void Main() { string nimi = "Tommi Lahtonen"; Console.WriteLine(nimi); VaihdaNimiEiToimi(nimi); Console.WriteLine(nimi); VaihdaNimi(ref nimi); Console.WriteLine(nimi); string vesa; AnnaNimi(out vesa); Console.WriteLine(vesa); TulostaNimet(nimi, vesa); Console.ReadKey(); } public static void VaihdaNimiEiToimi(string n) { n = "Lammi Tohtonen"; // tämä ei toimi } public static void VaihdaNimi(ref string n) { n = "Lammi Tohtonen"; } public static void AnnaNimi(out string n) { // Console.WriteLine(n); // ei toimi! n = "Vesa Lappalainen"; } public static void TulostaNimet(params string[] nimet) { foreach (string n in nimet) { Console.WriteLine("Nimi: {0}", n); } }
Properties
Käyttämällä propertyja on helppo hoitaa tiedon kapselointi:
private int m_ika = 20; public int ika { get { return m_ika; } set { if (value> 0) m_ika = value; }
Indeksoija
Indeksoija (indexer) on taulukkovastine propertyille
class taulukko { private string[] data; public taulukko(int koko) { data = new string[koko]; for (int i=0; i < koko; i++) { data[i] = "-"; } } public string this[int i] { get { return data[i]; } set { data[i] = value; } } static void Main() { int koko = 10; taulukko taul = new taulukko(koko); taul[1] = "Eka"; taul[2] = "Toka"; taul[3] = "Kolmas"; for (int i=0; i < koko; i++) { Console.WriteLine("taul[{0}]: {1}", i, taul[i]); } } }
enum
public enum VIIKKO { Maanantai, // saa arvon 0 Tiistai, // saa arvon 1 Keskiviikko, // jne. Torstai, Perjantai, Lauantai, Sunnuntai } // voidaan tehdä myös näin: public enum VIIKKO { Maanantai = 1, Tiistai = 2, Keskiviikko = 3, Torstai = 4, Perjantai = 5, Lauantai = 6, Sunnuntai = 7 } VIIKKO paiva = Tiistai; if ( paiva == VIIKKO.Torstai ) ...
Struct vs Class / arvotyypit vs referenssityypit
using System; /// <summary> /// esimerkki kloonattu C# Station-sivustolta /// </summary> class Employee { private string m_name; public string Name { get { return m_name; } set { m_name = value; } } } struct Duunari { private string m_name; public string Name { get { return m_name; } set { m_name = value; } } } class Program { static void Main() { Employee joe = new Employee(); joe.Name = "Joe"; Employee bob = new Employee(); bob.Name = "Bob"; Console.WriteLine("Original Employee Values:"); Console.WriteLine("joe = " + joe.Name); Console.WriteLine("bob = " + bob.Name); // kopioidaan bobiin referenssi joen tietoihin bob = joe; Console.WriteLine(); Console.WriteLine("Values After Reference Assignment:"); Console.WriteLine("joe = " + joe.Name); Console.WriteLine("bob = " + bob.Name); joe.Name = "Bobbi Jo"; Console.WriteLine(); Console.WriteLine("Values After Changing One Instance:"); Console.WriteLine("joe = " + joe.Name); Console.WriteLine("bob = " + bob.Name); Console.ReadKey(); Duunari joe2 = new Duunari(); joe2.Name = "Joe"; Duunari bob2 = new Duunari(); bob2.Name = "Bob"; Console.WriteLine("Original Duunari Values:"); Console.WriteLine("joe = " + joe2.Name); Console.WriteLine("bob = " + bob2.Name); // Kopioidaan joen tiedot bobiin bob2 = joe2; Console.WriteLine(); Console.WriteLine("Values After Value Assignment:"); Console.WriteLine("joe = " + joe2.Name); Console.WriteLine("bob = " + bob2.Name); joe2.Name = "Bobbi Jo"; Console.WriteLine(); Console.WriteLine("Values After Changing One Instance:"); Console.WriteLine("joe = " + joe2.Name); Console.WriteLine("bob = " + bob2.Name); Console.ReadKey(); } }
Copying, Cloning, and Marshalling in .NET
Poikkeukset
using System; using System.IO; namespace testi { class Poikkeukset { public static void Main() { try { using (StreamReader sr = new StreamReader("Testi.txt")) { string line; while ((line = sr.ReadLine()) != null) { Console.WriteLine(line); } } } catch (Exception e) // napataan kiinni kaikki virhetilanteet { Console.WriteLine("Tiedostoa ei saada avattua:"); Console.WriteLine(e.Message); } try { int luku1 = 5; int luku2 = 0; int tulos = luku1 / luku2; throw new System.Exception("foobar"); // aiheutetaan itse virhe } catch (System.DivideByZeroException e) { Console.WriteLine("Yritettiin jakaa nollalla"); } catch (Exception e) // napataan kiinni kaikki virhetilanteet { Console.WriteLine(e.Message); } finally // suoritetaan aina { Console.ReadKey(); } } } }
Design Guidelines for Exceptions
Debuggaus
Breakpointin voi asettaa hiirellä kontekstivalikosta tai suoraan napauttamalla koodi-ikkunan vasenta laitaa.
Debug-valikosta löytyvät tarpeelliset toiminnot.
Avustus
.NET-kirjastojen avustus löytyy parhaiten MSDN-sivuilta. Esim:
Sama pätee C#-ohjeisiin. Esim:
Reading From a Text File (Visual C#)
Käyttäjien kommentit