You are on page 1of 10

Szoftverfejlesztés Tanszék Szegedi Tudományegyetem

C# alapok
Az óra célja egy alap nyelvi tudás biztosítása. Feltételezzük, hogy a hallgató
teljesítette a Programozás { Alapjai, I, II } kurzusokat, illetve az Alkalmazásfe-
jlesztés I-et, így ismeri a C, C++ és Java nyelveket. Ez lehetővé teszi, hogy az
órán ne az alap konstrukciókkal foglalkozzunk, hanem a C# nyelv tulajdonsá-
gaival.
Az anyag a Reiter István C# programozás lépésről lépésre könyv példáit veszi
alapul, melyek során az eszköztár bemutatásra kerül.

Típusok

Referencia és értéktípusok

Mint ahogy a Java nyelvből már ismerős lehet, a C#-ban is minden típus egy
ősosztályból származik. Jelen esetben ez az ősosztály a System.Object. A közös
ősosztályon felül viszont megkülönböztetünk érték és referenciatípusokat.
A referenciatípusú objektumok a heapen foglalnak helyet, míg az értéktípusú
változók a stacken (kivéve, ha egy referenciatípusú objektum adattagjai). Ez az
információ segít abban, hogy függvények paramétereinek átadását megérthessük.
• értéktípus: char, enum, bool, struct, int, float, double, . . . (minden
beépített numerikus típus)
• referenciatípus: string, saját és beépített osztályok, delegate
Amikor egy referenciatípusú változót értékül adunk egy másiknak, akkor nem
érték szerint fog lemásolódni, hanem a két változó ugyanarra a memóriaterületre
(objektumra) fog mutatni. Ezért, ha az egyiket változtatjuk, akkor mindkét
változón keresztül látott érték változni fog.
double variable = 3.14;
double another = variable;
another = 2.72;

Console.WriteLine(variable);
class RefType {
public double valueType;
}
// ...
RefType rt = new RefType();
rt.valueType = 3.14;

RefType another = rt;


another.valueType = 2.71;
Console.WriteLine(rt.valueType);

1
Szoftverfejlesztés Tanszék Szegedi Tudományegyetem

Konstansok

A konstansokat két különálló kulcsszóval tudjuk létrehozni: const és readonly.


A const kulcsszó segítségével egy objektumot nem módosíthatóvá tehetünk.
Ebben az esetben deklaráció és a definíció egyszerre kell megtörténjen. A
readonly módosítóval ellátott objektumok is módosíthatatlanok, viszont itt a
deklaráció és a definíció szétválik, a definíciónak elég a konstruktorban megtörtén-
nie.

Nullable típusok

Amikor egy referenciatípusú változót deklarálunk, a keretrendszer automatikusan


null értékkel inicializálja (azaz nem mutat sehova). Az értéktípusú változók
ezzel szemben alapértelmezett értékekre inicializálódnak (pl. int: 0, bool: false),
és kézzel sem tudjuk a null értéket beállítani.
Ahhoz, hogy ezekhez a változókhoz is hozzá tudjuk rendelni a még nem definiált
jelzőt, használnunk kell a C# nullable típusmódosítóját. Ez két módszerrel
történhet:
int? nullableInt = null;
Nullable<int> anotherNullable = null;

if (nullableInt.HasValue)
Console.WriteLine(nullableInt.Value);

if (anotherNullable == null)
anotherNullable = 3;

Implicit típusok

A nyelv szigorúan típusos, az implicit típusok csak kényelmi szolgáltatásként


érthetők. A var kulcsszó használatakor a változó típusát a fordító a jobb oldali
kifejezésből fogja “kitalálni”. Beépített típusoknál nem szokás használni.
var rt = new RefType();
rt.valueType = 3.14;
Az rt változó RefType típusú és a kódrészlet teljesen ekvivalens a RefType rt
= new RefType(); sorral.

2
Szoftverfejlesztés Tanszék Szegedi Tudományegyetem

Névtelen típusok

Amennyiben egy típus használatához nincs szükségünk a konkrét megnevezésére,


akkor használhatunk névtelen (anonumous) típusokat.
var anonymVariable = new { id=0, city="Szeged" };
Console.WriteLine(anonymVariable.city);

Osztályok

Osztályokat a class kulcsszóval tudunk létrehozni. Az öröklődést a C++-hoz


hasonlóan class Child : Base konstrukcióval tudjuk megvalósítani. A C++-
től eltérően a C# nem támogatja a többszörös öröklődést, így egy osztálynak
csak egy őse lehet, viszont több interfészt is implementálhat.

Adattagok láthatósága

Módosító Jelentése az adattagra nézve


public Az elérés nincs korlátozva.
protected Csak a tartalmazó osztályból és leszármazottaiból elérhető.
private Csak a tartalmazó osztályból elérhető.
internal Csak a tartalmazó assembly-ből elérhető.
protected Csak a tartalmazó assembly-ből vagy a leszármazott
internal osztályokból elérhető.
private Csak a tartalmazó osztályból vagy a tartalmazó assembly-n
protected belül leszármazott osztályokból elérhető.

Az osztályokban létrehozott adattagok alapértelmezett láthatósága private.

Parciális osztályok

A nyelv megengedi, hogy az osztályokat több részletben definiáljuk, ezeket


nevezzük parciális (partial) osztályoknak. Minden részletnél ki kell írni a
partial class-t ugyanazzal a láthatósági módosítóval, különben fordítási hibát
kapunk.
Ezek az osztályok főként WinForms-nál fognak előkerülni, amikor az osztály
egyik részét a fejlesztőkörnyezet generálja (GUI összekattintgatás -> kód), a
másik felét pedig a programozó írja (eseménykezelés).

3
Szoftverfejlesztés Tanszék Szegedi Tudományegyetem

// PartialClass.cs
public partial class PartialClass {
public int FirstPart { get; set; }
}

// Program.cs
public partial class PartialClass {
public void PrintToConsole() {
Console.WriteLine(FirstPart);
}
}

class Program {
static void Main(string[] args) {
var pClass = new PartialClass();
pClass.FirstPart = 3;
pClass.PrintToConsole();
}
}

Interfészek

Az interfész magában meghatároz egy függvényhalmazt, melyet az interfészt im-


plementáló osztálynak meg kell valósítania. A nyelv nem támogatja a többszörös
öröklődést, így egy osztálynak csak egy őse lehet, viszont több interfészt is meg-
valósíthat. Míg az osztályok esetében az alapértelmezett láthatósági módosító
private, az interfészek esetében ez public.
Tartalmazhat:
• metódusokat
• propertyket
• indexelőket
• eseményeket (következő óra)
interface ISample { void SampleMethod(); }

class Implmentation : ISample {


void SampleMethod() { /* ... */ }

static void Main() {


var obj = new Implmentation();
obj.SampleMethod();
}
}
Amennyiben egy osztály több interfészt implementál, akkor vesszővel elválasztva

4
Szoftverfejlesztés Tanszék Szegedi Tudományegyetem

kell felsorolni őket. Ha több interfész deklarálná a SampleMethod-ot, akkor az


implementációnak expliciten ki kell mondania, hogy melyiket valósítja meg.
class Implmentation : ISample, ISample2 {
void ISample.SampleMethod() { /* ... */ }
void ISample2.SampleMethod() { /* ... */ }
}
Ha az interfészeken kívül az osztály öröklődik egy másik osztályból, akkor az
öröklődésnek kell az első helyre kerülnie, majd az interfészlista. A példából
látható, hogy az elnevezési konvenció szerint egy I betű kerül minden interfész
neve elé: IInterfaceName.

Tulajdonságok

A tulajdonságok (property) egy speciális adattagja az osztálynak, mely lehetővé


teszi privát változók kontrollált hozzáférését. Első ránézésre adattagok, viszont
speciális metódusok legtöbbször publikus láthatósággal ellátva.
A get használható a változó értékének elkérésére, a set pedig a beállítására.
Mindkét esetben lehetőség van különböző validációk és számítások elvégzésére
mielőtt visszaadnánk (vagy beállítanánk) az értéket.
Szerencsére a property-ket nem kell kézzel írnunk, a fejlesztőkörnyezet biztosít
gyorsbillentyűket a létrehozásukhoz.
• prop + TAB + TAB
public int MyProperty { get; set; }
• propfull + TAB + TAB
private int myVar;

public int MyProperty {


get { return myVar; }
set { myVar = value; }
}
Amennyiben az alapértelmezetten felül szeretnénk valami számítást vagy
validálást a get és a set blokkokban, akkor azt így tehetjük meg:

5
Szoftverfejlesztés Tanszék Szegedi Tudományegyetem

private int myVar;

public int MyProperty {


get { return myVar * 3; }
set {
if (value < 1 || value > 500) {
myVar = 0;
} else {
myVar = value;
}
}
}

Kiterjesztett metódusok

Már létező típusokhoz új metódusokat tudunk hozzáadni anélkül, hogy azokat


módosítanánk vagy származtatnánk belőlük. Ezeket extension method-oknak
nevezzük (és maradjunk az angol névnél). Ahhoz, hogy egy ilyen metódust
létrehozzunk, egy statikus osztályt kell létrehoznunk egy statikus metódussal.
public static class StringReverser {
public static string Reverse(this string input) {
char[] array = input.ToCharArray();
Array.Reverse(array);
return new String(array);
}
}
// ...
string alkfejl = "Alkalmazasfejlesztes II";
Console.WriteLine(alkfejl);
Console.WriteLine(alkfejl.Reverse());

Metódusok

Referencia szerinti paraméterátadás

Paraméterek átadása történhet érték és referencia szerint is. Érték szerinti átadás
esetében a paraméter lemásolódik és a metódus ezt a másolatot kapja meg. A
referencia szerinti paraméterátadásnál egy objektumra mutató referencia kerül
átadásra, nem történik másolás. Ily módon a függvényen belül történt változások
láthatók a függvényhívás után is.
Fontos kiemelni, hogy a referenciával kapott paraméter (objektum) állapotát
módosíthatjuk, magát a referenciát nem. Amennyiben a függvényen belül egy

6
Szoftverfejlesztés Tanszék Szegedi Tudományegyetem

új objektumot hozunk létre, azt hozzárendeljük a paraméterhez, ez nem fog


látszódni a függvény lefutása után.
Ha szeretnénk módosítani a referenciatípusú paraméter referenciáját, azt külön
jelezni kell a paraméterlistában a ref módosítóval. A parciális osztályban
bemutatott példa továbbgondolása következik.
static void DoMagic(PartialClass p) {
p.FirstPart = 5;
}
static void Main(string[] args) {
var pClass = new PartialClass();
pClass.FirstPart = 3;
pClass.PrintToConsole();

DoMagic(pClass);
pClass.PrintToConsole();
}
static void DoMagic(PartialClass p) {
p = new PartialClass();
}
static void Main(string[] args) {
var pClass = new PartialClass();
pClass.FirstPart = 3;
pClass.PrintToConsole();

DoMagic(pClass);
pClass.PrintToConsole();
}

7
Szoftverfejlesztés Tanszék Szegedi Tudományegyetem

static void DoMagic(ref PartialClass p) {


p = new PartialClass();
}
static void Main(string[] args) {
var pClass = new PartialClass();
pClass.FirstPart = 3;
pClass.PrintToConsole();

DoMagic(ref pClass);
pClass.PrintToConsole();
}

Out paraméter

Referencia szerinti paraméterátadásnál már inicializált paramétert kell átadnunk.


Lehetőség van inicializálatlan paramétert is átadni az out kulcsszó segítségével,
ami azt jelzi, hogy a függvény a futása során inicializálni fogja azt.
Erre példa a public static bool TryParse (string s, out int result);.
A függvény igaz értékkel tér vissza, ha sikerült a szöveget számmá konvertálnia,
és a result változóban adja vissza az eredmény számot.
if (int.TryParse(Console.ReadLine(), out int result)) {
Console.WriteLine(result);
}

Alapértelmezett és opcionális paraméterek

Függvények paraméterlistájában lehetőség van alapértelmezett értékek


megadására. Ezeknek a paraméterlista végén kell szerepelniük, és függvény-
híváskor nem kötelező ezeket a paramétereket átadni.
public void ExampleMethod(int required,
string optionalstr = "def",
int optionalint = 10) { /* ... */ }

ExampleMethod(5);
ExampleMethod(5, "custom");
ExampleMethod(5, "custom", 1);
ExampleMethod(3, optionalint: 4);

8
Szoftverfejlesztés Tanszék Szegedi Tudományegyetem

Órai munka

A gyakorlat hátralevő részében egy Számológép alkalmazást kell írni:


• Új .NET Core konzolalkalmazás legyen
• * 5 4 alakban várja az alkalmazás a sorokat a konzolról (string.Split())
• * = { +, -, *, / }
• Ha nem jó a formátum, írja ki, hogy “Rossz formátum, helyes pl. + 5 4”
• Egy jó sor után írja ki az eredményt az alkalmazás és várjon újabb inputot
amíg az “exit” sor nem érkezik.

9
Szoftverfejlesztés Tanszék Szegedi Tudományegyetem

Hivatkozások

Reiter István - C# programozás lépésről lépésre


https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/access-
modifiers
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/value-
types
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/reference-
types
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-
and-structs/constants
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/nullable-
types/
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-
and-structs/implicitly-typed-local-variables
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-
and-structs/partial-classes-and-methods
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interface
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-
and-structs/properties
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-
and-structs/extension-methods
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-
and-structs/passing-parameters

10

You might also like