C#-perusteet
- 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