C Sharp

A Wikipédiából, a szabad enciklopédiából
A szócikk címe technikai okok miatt pontatlan. A helyes cím: C#.
C#
Paradigma objektumorientált
Jellemző kiterjesztés .cs
Megjelent 2001
Tervező Microsoft
Fejlesztő Microsoft
Utolsó kiadás 5.0 (2012. augusztus 15.)
Típusosság statikus, dinamikus, erősen típusos, típus biztos, normatív
Dialektusok Cω, Spec#, Polyphonic C#
Megvalósítások .NET Framework, Mono, DotGNU
Hatással volt rá Java, C++, Object Pascal, Eiffel
Befolyásolt nyelvek Java 5, F#
Weboldal


A C# (kiejtése: szí-sárp) a Microsoft által a .NET keretrendszer részeként kifejlesztett objektumorientált programozási nyelv. A nyelv alapjául a C++ és a Java szolgált. A C# fejlesztését döntően befolyásolta, hogy a Microsoft a saját Java keretkörnyezetét a saját operációs-rendszer specifikus függvényeivel és szolgáltatásaival bővítette ki, melyre nem volt engedélye, ezért a Java fejlesztői beperelték őket, mivel így számos Java alkalmazás csak Windows rendszerben volt képes működni. Ezt követően a Microsoft a Java eltávolítására kényszerült a Windows rendszerekből (természetesen a Java-t a továbbiakban is lehet külön rendszerként telepíteni) és egy saját keretrendszer fejlesztésébe kezdett. Ez lett a .NET (kiejtése: dotnet), és ezen keretrendszerhez adták ki nyelvként a C# első verzióját. A későbbiekben ezt a nyelvet úgy fejlesztették tovább, hogy meglegyen az egyensúly a programozó nyelvi szabadsága és a gyors alkalmazásfejlesztés lehetősége között. Rengeteg hivatalosan kiadott bővítmény létezik hozzá, amelyek a kódolást könnyebbé teszik.

A nyelv fejlesztését Anders Hejlsberg vezette, aki a Turbo Pascal tervezője volt. Bár a Mono Project egy nagyrészt kompatibilis[1] nyílt forráskódú C# fordítót állított elő, ami lehetővé tette ilyen kódok futtatását Linux, vagy Macintosh rendszereken, a nyelv Windows operációs rendszereken kívüli használata nem terjedt el, mivel az osztálykönyvtárakat szolgáltató .NET Framework portolása más rendszerek alá még kezdetleges stádiumban van.[forrás?] Ugyanakkor a Mono az utóbbi években rohamos fejlődésnek indult, amit elősegített a Microsoft és a Novell (a Mono „anyacége”) együttműködése a Microsoft Silverlight technológiájának Linux illetve Macintosh rendszerekkel kompatibilis változatának – a Moonlightnak – a készítésekor.

Áttekintés[szerkesztés | forrásszöveg szerkesztése]

A C# az a programozási nyelv, ami a legközvetlenebb módon tükrözi az alatta működő, minden .NET programot futtató .NET keretrendszert, valamint erősen függ is attól: nincsen nem menedzselt, natív módban futó C# program. A primitív adattípusai objektumok, a .NET típusok megfelelői. Szemétgyűjtést használ, valamint az absztrakcióinak többsége (osztályok, interfészek, delegáltak, kivételek…) a .NET futtatórendszert használja közvetlen módon.

A C vagy C++ nyelvhez hasonlítva a C# több korlátozást és továbbfejlesztést is tartalmaz. A lehetőségei közül néhány:

  • A mutatók és a nem ellenőrzött aritmetika csak egy speciális, nem biztonságos módban (unsafe mode) használható. A legtöbb objektum-hozzáférés csak biztonságos hivatkozásokon keresztül tehető meg, és az aritmetikai műveletek debug módban túlcsordulás szempontjából ellenőrzöttek.
  • Az objektumok nem szabadíthatók fel közvetlen módon, ehelyett a szemétgyűjtő szabadítja fel őket, mikor már nincs rájuk hivatkozás. Ez a módszer kizárja a nem létező objektumokra való hivatkozás lehetőségét.
  • A destruktorok (~) elérhetőek. A megfelelően megírt IDisposable interfész (Disposable programozási minta), aminek a lefutását garantálja using blokk, együtt kikényszerítheti az azonnali felszabadítást az osztályon belüli natív erőforrások esetében. A nem natív erőforrások felszabadítását ebben az esetben is a szemétgyűjtő (Garbage Collector) végzi. A finalizerek szintén rendelkezésre állnak, de nem váltanak ki azonnali felszabadítást. Finalizer a Dispose eljárás javasolt implementációs módozatában nem fut le, mivel az ajánlás szerint a szemétgyűjtőt utasítani kell a finalizer hívás kihagyására.
  • A nyelv csak egyszeres öröklődést támogat, de egy osztály több interfészt is megvalósíthat.
  • A C# sokkal típusbiztosabb, mint a C++. Az egyetlen implicit konverzió a biztonságos konverzió, úgy mint az egészek tágabb intervallumba konvertálása vagy a leszármazott osztályok alaposztályba konvertálása. Nincs implicit konverzió az egészek és a logikai típus (boolean) között, a felsorolás tagok és az egészek között. Nincsenek void mutatók (bár az Object osztályra mutató mutatók hasonlóak), valamint bármely, a felhasználó által definiált implicit konverziót explicit módon meg kell jelölni.
  • A felsorolás adattagjai a saját névterükben helyezkednek el.
  • A 2.0-s verziótól felfelé már rendelkezik a generikus programozás néhány eszközével.
  • Tulajdonságok (Properties) használhatók, amelyek úgy tesznek lehetővé kódfuttatást mezők beállításakor és olvasásakor, hogy közben az adattagok szintaxisát használja.

Összehasonlítás a Java-val[szerkesztés | forrásszöveg szerkesztése]

A Microsoft bár úgy fejlesztette ezt a nyelvet, mint a saját Java implementációját, bizonyos tulajdonságokban azonban eltérő szemléletmódot követ a két rendszer. Ilyen különbségek például:

  • A Java alapértelmezett láthatósága mindig csomagon (package) belül publikus, a C#-nál mindig privát, a protected jelentése eltér, illetve támogatja az internal, protected internal láthatóságot
  • A C# támogatja a parciális osztályokat (2.0-s verziótól felfelé), és az operátor-felüldefiniálást (en:Operator Overloading)
  • A metódusok a Javaban alapból virtuálisak, ellentétben a C#-pal
  • A C#-ban vannak lambda-kifejezések (3.0-s verziótól)
  • A Java ellenben például lehetővé teszi a fordításidejű kivételkezelést
  • A Java támogatja az egzisztenciális generikusokat, míg a C# a ko- és kontravarianciát (4.0-s verziótól) a generikusoknál
  • A C# támogatja az azonos nevű, de eltérő verziójú szerelvények betöltését, ezzel szemben a Java-ban nincs ilyen támogatás

Szintaxisban a két nyelv ugyanabba a nyelvcsaládba (C/C++ alapú nyelvek) tartozik, tehát mindkettőre a kapcsos zárójeles tagolás, sor végi pontosvessző a jellemző, ezért a kód nagyban hasonlít.

Kódkönyvtárak[szerkesztés | forrásszöveg szerkesztése]

A legtöbb programozási nyelvtől eltérően a C# megvalósítások nem rendelkeznek önálló, eltérő osztály- vagy függvénykönyvtárakkal. Ehelyett a C# szorosan kötődik a .NET keretrendszerhez, amitől a C# kapja a futtató osztályait és függvényeit. A .NET keretrendszer osztálykönyvtárat tartalmaz, ami a .NET nyelvekből felhasználható egyszerű feladatok (adatreprezentáció és szövegmanipuláció) végrehajtásától kezdve a bonyolult (dinamikus ASP.NET weblapok generálása, XML feldolgozás és reflexió) feladatokig. A kód névterekbe van rendezve, mely a hasonló funkciót ellátó osztályokat fogja össze. Például System.Drawing a grafikai, System.Collections az adatstruktúra és System.Windows.Forms a Windows ablakos megjelenítéséért felelős funkciókat fogja össze.

További rendezési szint az assembly (szerelvénynek fordították, nem elterjedt). Egy assembly állhat egy fájlból, vagy több összelinkelt fájlból (az al.exe segítségével), ami több névteret és objektumot tartalmazhat. A különböző feladatokhoz szükséges osztályokat assemblyk (például System.Drawing.dll, System.Windows.Forms.dll) hivatkozásával vagy a központi könyvtár (mscorlib.dll a Microsoft megvalósításában) használatával érhetik el a programok.

A .NET keretrendszer támogatja azonos nevű, de eltérű verziójú Assembly-k betöltését, amelyek verziózott implementációkat tartalmazhatnak, így könnyedén lehetővé válik egy alkalmazáson belül a visszafelé kompatilitás eltérő implementációk betöltésével és páldányosításával.

Története[szerkesztés | forrásszöveg szerkesztése]

A .NET osztálykönyvtárait a programozók eredetileg egy sajátos, ún. SMC (Simple Managed C) nyelven írták. 1999-ben azonban Anders Hejlsberg (aki addig a J++ nyelven dolgozott) vezetésével egy csapat alakult egy új programozási nyelv létrehozására, akkoriban COOL (C-like Object Oriented Language, magyarul: C-szerű Objektum Orientált Nyelv) fedőnév alatt.[2] A cél egy olyan nyelv volt, mellyel teljesen objektumorientált módon lehet a keretrendszer komponenseit fejleszteni. Egy évvel később, 2000 júliusában a PDC konferencián a .NET-tel, és az ASP.NET-tel együtt a C#-ot is bemutatták, immár ezen névvel, hogy az esetleges szerzői jogi problémákat megelőzzék. Bár sok bírálat érte megjelenésekor, főleg a Java-s táborból, miszerint a Microsoft pusztán legyártotta a saját Java verzióját, Anders azt nyilatkozta, hogy a nyelvet sokkal inkább a C++-hoz szerették volna közelíteni.[3]

Verziók[szerkesztés | forrásszöveg szerkesztése]

Napjainkban a nyelv a 4.0-ás verziónál tart, és az 1.0-áshoz képest rengeteg újdonságot tartalmaz.

Verziószám Megjelenés Főbb újdonságok
2.0 2005 november Generikus és parciális típusok, anonim metódusok, iterátorok
3.0 2007 november Implicit módon megadott lokális változók, lambda-, és lekérdezés-kifejezések, kifejezésfák, objektum inicializálók
4.0 2010 április Dinamikus kötés, opcionális paraméterek, generikus ko- és kontravariancia

Szabványosítás[szerkesztés | forrásszöveg szerkesztése]

A Microsoft benyújtotta a C# nyelvi specifikációját az ECMA-hoz formális szabványosításra. 2001 decemberében az ECMA kiadta az ECMA-334 C# Language Specification szabványt, 2003-ban pedig ISO szabvány lett (ISO/IEC 23270). Több független megvalósítás is folyamatban van, többek között:

Példaprogramok[szerkesztés | forrásszöveg szerkesztése]

Egy egyszerű C# program:

public class ExampleClass
{
  public static void Main()
  {
    System.Console.WriteLine("Helló világ!");
  }
}

A program megjeleníti a Helló világ! szöveget a konzolon. A program részletei a következők:

public class ExampleClass

Ez az osztálydeklaráció. Publikus, azaz bármely más projekt szabadon használhatja az osztályt. Az összes információ a kapcsos zárójelek között az osztály leírását szolgálja. Minden programban kötelező legalább egy osztályt implementálni, itt ennek neve ExampleClass lett.

public static void Main()

Ez a függvény a program belépési pontja, ahol a program végrehajtása megkezdődik, mindig a Main() nevet viseli.

System.Console.WriteLine("Helló világ!");

Ez rész felel meg a feladat végrehajtásának. A Console egy rendszerobjektum, ami egy parancssort jelképez. A Console objektum WriteLine metódusának meghívása a paraméterként átadott szöveget kiírja a parancssorba.

Változók és deklarációk[szerkesztés | forrásszöveg szerkesztése]

Ahhoz, hogy értékeket tudjunk megadni, először változót kell deklarálni, és utána inicializálni azt. deklaráció: int x; inicializálás: x = 10; Ezt lehet egyszerre is: int x = 10;

Egy példa a változókra:

class valtozok
{
    public static void Main()
    {
        int i = 10;                       // egész típusú i változó értéke 10
        System.Console.WriteLine(i);     // kiírjuk a képernyőre
 
        int i2 , i3;                       // többszörös deklarálás
        i2 = 12;                         //inicializáció
        i3 = 13;
        Console.WriteLine(i2);
        Console.WriteLine(i3);
 
        const double Allando = 3.1415;   //egy állandó deklarációja és inicializálása
        double d = 12.3;                         //tizedestört
        float f = 0.65F;        //AZ F betűvel jelezzük, hogy lebegőpontosan ábrázolandó
 
        char c = 'c';   // a char 1 karaktert tud tárolni(és azt ''jelek között kell megtenni
        string s = "Hello World!"; // a string karaktersorozatot tud tárolni "" jelek között
        Console.WriteLine("double: {0}, float: {1}, char: {2}, string: {3},  allando: {4}",d,f,c,s,Allando); //kiírjuk a képernyőre az eredményeket. A {0}helyére a d a {1}helyére az f... fog kerülni.
        Console.ReadKey(); // a program egy billentyű lenyomására vár, //tehát nem fog lefutni a programunk míg meg nem nyomunk egy gombot.
    }
}

Operátorok[szerkesztés | forrásszöveg szerkesztése]

Matematikai:

Az operátorok műveletek: +, -, *, /, %(maradékképzés). A C++-ban bevezetett jelölések itt is léteznek, tehát például:

i = i+1; ez ugyanaz, mint ez: i++;

i = i+d; ez ugyanaz, mint ez: i += d;

i = i*d; ez ugyanaz, mint ez: i *= d;...

Relációs:

Egy relációs jel segítségével két érték között végezhetünk viszonyításokat. pl: < >, <= >=, !=(nem egyenlő), ==(egyenlő)...

példa:

...
        int x = 10;
        int y = 23;
        Console.WriteLine(y < x); // kiírja az eredmény false (hamis)
        Console.WriteLine(y == x); // false
        Console.WriteLine(y != x); //true (igaz)
        Console.WriteLine(x <= y); // x kisebb (vagy egyenlő) mint y true...
        Console.ReadKey();
...

Logikai / feltételes operátorok:

A logikai műveletek is elérhetőek hasonlóan a kiinduló nyelvekhez:

  • && : és
  • || : vagy
  •  ! : negáció
  • stb.

példa:

...
        bool igaz = true; // igaz igaz
        bool hamis = false; // hamis hamis
        if( igaz == false || hamis == false ) // ha igaz hamis vagy hamis hamis akkor kiírja a szöveget.
        {
            System.Console.WriteLine("Az egyik jo volt");
        }
...

Vezérlési szerkezetek[szerkesztés | forrásszöveg szerkesztése]

Elágazások (szelekciók)[szerkesztés | forrásszöveg szerkesztése]

Az elágazás valamilyen feltételtől függő tevékenység végrehajtását jelenti. Két alapvető fajtája van: a kétágú és a többágú szelekció. Kétágú szelekció esetén (if, else) a program futása vagy az igaz vagy a hamis ágon folytatódik. Többágú szelekciónál lehetőség van egy kifejezés eredményének több lehetséges állapotától függő tevékenység elvégzésére.

Példa:

...
        Console.WriteLine("Adjon meg egy számot:");
        int x = Convert.ToInt32(Console.ReadLine()); // bekérünk egy egész típusú számot, ha nem is egész típusú akkor is az lesz mivel átkonvertáljuk.
 
        switch(x) // vizsgáljuk az x-et
        {
            case 17: // ha 17
                Console.WriteLine("x == 17");
                break; // leállítjuk
            case 10: //ha 10
                Console.WriteLine("x == 10");
                break; // leállítjuk
            default: // ha egyik sem
                Console.WriteLine("Default");
                break; // leállítjuk
        }
...

Ciklusok (iterációk)[szerkesztés | forrásszöveg szerkesztése]

Amikor egy adott utasítás vagy utasítássorozatot többször kell elvégeznünk akkor ciklust használunk, például: ki kell írni a konzolra 0-100-ig a számokat. A ciklusoknak alapvetően három típusa létezik: a számlálásos, az elöltesztelős és a hátultesztelős. A számlálásos ciklus egyik megvalósítási formája a for ciklus:

        for(int i = 0; i <= 100; i++) //addig fog ismétlődni a ciklus, amíg i el nem éri a 100-at
        {
            System.Console.WriteLine(i);
        }

Elöltesztelős ciklus a while kulcsszóval érhető el:

        int i = 0;//kezdőérték beállítása
        while( i <= 100 )// ciklusfeltétel megadása
        {
            System.Console.WriteLine(i);
            i++; //ciklusváltozó növelése
        }

Hátultesztelős a do-while párossal:

        do
        {
            Console.WriteLine("adjon meg ketto szamot");
            int egyik = Convert.ToInt32(Console.ReadLine());
            int masik = Convert.ToInt32(Console.ReadLine());
 
            int eredmeny = egyik + masik;
            Console.WriteLine("Az osszeguk: {0}", eredmeny);
 
            Console.WriteLine("Ha ki akar lepni usse be, hogy kilepes, ha nem akkor azt, hogy vissza");
            valasztas = Convert.ToString(Console.ReadLine());
 
        }
        while (valasztas != "kilepes"); // igaz, akkor is vissza lép, ha nem a vissza-tütjükbe, a feltétel az, hogy ne kilepes legyen.

Létezik a C#-ban még egy különlegesebb ciklusvezérlő, ez a foreach. Egy adott tömb, vagy lista elemein megy végig, a különlegessége, hogy nem kell megadni kilépési pontot, sem feltételt, egyszerűen akkor marad abba, ha a végére ér az adott adatstruktúrának. Használata javasolt, mivel írásmódja szebb, mint a hagyományos for ciklusé, és a belőle forduló kód a legtöbb esetben optimálisabb CIL kódot eredményez a többi módszerhez képest.[4] Példa:

...
        int[] szamok = new int[7]{1,3,2,5,7,4,9};
        int paros = 0;
        int paratlan = 0;
 
        foreach( int i in szamok )
        {
            if (i % 2 == 0) paros++; 
            else paratlan++;
        }
...

Felsorolástípus (enum)[szerkesztés | forrásszöveg szerkesztése]

A felsorolás típust akkor szoktuk használni, ha sok elemet akarunk megadni. Ez az összegyűjtés (enumeration) magától megszámozza az elemeket 0 -...-ig, de ha saját számozást akarunk, akkor magunk is megszámozhatjuk. Például:

class EnumClass
{
    enum szinek{piros, kek, zold, sarga};
 
    public static void Main()
    {
        System.Console.WriteLine(szinek.zold); // kiírja a színt
 
        //ciklus a szineken történő végighaladásra
        for( szinek i = szinek.piros; i <= szinek.sarga; i++)
        { // i = piros, piros kisebb és egyenlő sarga ( piros<kek<zold<sarga )
            System.Console.WriteLine(i);
        }
        System.Console.ReadKey();
    }
}

Tömbök[szerkesztés | forrásszöveg szerkesztése]

A tömb az az adattípus, amikor egy adott típusú változóból egy sorozatot, vagy vektort, mátrixot készítünk. Általános szintaxis: Típus[] változónév = new Típus[hossz];. Például:

class Tombok1
{
    public static void Main()
    {
        int[] szamok = new int[5] {1,3,6,3,2}; // létrehozunk egy tömböt és utána megadjuk az elemeit
        int[] szamok2;
        szamok2 = new int[] {3,6,1,6,8,3}; // az elemek számából magától kiszámolja, hogy hány elemű...
 
        string[] karakterLanc = new string[3] {"egy","ketto","harom"};
 
        Console.WriteLine("A szamok tomb 4. elemenek erteke: {0}", szamok[4]);
        Console.WriteLine("A szamok2 tomb 3. elemenek erteke: {0}", szamok2[3]);
 
        // ciklus, mely végig halad a tömb elemein
        for( int i = 0; i < karakterLanc.Length; i++ ) Console.WriteLine(karakterLanc[i]);
        Console.ReadKey();
    }
}

OOP programozás (objektum orientált)[szerkesztés | forrásszöveg szerkesztése]

class OOP
{
    public int x; //publikus elérésű egész x
    private int y; //private tehát nem lehet elérni másik osztályból
    public int Y   //itt egy tulajdonság, mely tulajdonságot ad az y private változónak, hogy el lehessen érni
    {
        get  { return y; }
        set  { y = value; }
    }
}
 
class NewClass // egy másik osztály
{
    public static void Main()
    {
        OOP szarmaztat = new OOP(); // származtatunk az OOP osztályból, hogy elérhessük annak az osztálynak a tartalmát
        szarmaztat.x = 17;  // az OOP osztály x változója = 17
        szarmaztat.Y = 18;  // a set blokkon keresztül értéket adunk az Y-nak és aztán azt az értéket visszaadjuk az get blokk segítségével //az y-nak
        Console.WriteLine("x = {0}, y = {1}", szarmaztat.x, szarmaztat.Y); // x = 17, y = 18
        Console.ReadKey();
    }
}

Osztályok láthatósága a C#-ban (zárttól a nyitott felé):

  • private: nem lehet elérni másik osztályból. Alapesetben minden osztály, metódus, stb. ilyen.
  • protected: származtatott osztályból érhető el.
  • internal: azonos assembly-ből elérhető
  • protected internal: fenti két csoport uniója
  • public: bárhonnan elérhető

Struktúra[szerkesztés | forrásszöveg szerkesztése]

A struktúra egy másik adatszerkezet a nyelven belül, mely nagyban hasonlít az osztályra. A fő különbség az, hogy míg az osztály minden adattagját referencia típusúként tárolja, addig a struktúra érték szerint adja meg őket. Ez akkor válik nyilvánvalóvá, amikor pl. egyedet másolunk. Ha objektumról (osztályról) van szó, és a másolatban megváltoztatunk egy adott adattagot, akkor az a tulajdonság az eredeti egyedben is megváltozik. Ellenben, ha struktúráról beszélünk, akkor másolatnál egy teljesen új memóriaterületre íródik le az új adattag, ezért ha azt meg is változtatjuk, az az eredetit nem befolyásolja.[5]

struct struktura_1
{
    public int kor;
    private string nev; // mivel private létre kell hoznunk egy értékadó tagfüggvényt.
    public string Nev
    {
        get return nev;
        set nev = value;
    }
}
 
public class struktura_hasznal
{
    public static void Main()
    {
        struktura_1 adatok = new struktura_1(); // példányosítunk
        adatok.kor = 14;
        adatok.Nev = "Terbe Daniel";
        Console.WriteLine("Az eletkorom: {0}, a nevem: {1}", adatok.kor, adatok.Nev);
        Console.ReadKey();
    }
}

Egy másik különbség, hogy struktúráknak nem adhatunk meg paraméter nélküli konstruktort, automatikusan generálódik hozzá egy. Amennyiben fontos számunkra a struktúra érvényessége, készíthetünk hozzá ellenőrző metódust.[6]

Egy különleges alkalmazási formája a csak olvasható struktúra, amelyek használata javasolt elemi, adattároló struktúrák esetén.[7]

Források[szerkesztés | forrásszöveg szerkesztése]

  1. Compatibility (angol nyelven). mono-project.com, 2011. december 19. (Hozzáférés: 2012. július 5.)
  2. How ASP.NET began in Java (angol nyelven). The Register, 2007. október 30. (Hozzáférés: 2012. július 5.)
  3. John Osborn: Deep Inside C#: An Interview with Microsoft Chief Architect Anders Hejlsberg (angol nyelven) (html). windowsdevcenter.com, 2010. január 8. (Hozzáférés: 2012. július 5.)
  4. Brian Pautsch: Item 11: Prefer foreach Loops (angol nyelven). Keylimetie, 2005. július 18. (Hozzáférés: 2012. július 5.)
  5. Classes and Structs (C# Programming Guide) (angol nyelven) (aspx). MSDN. (Hozzáférés: 2012. július 5.)
  6. Hide parameterless constructor on struct (angol nyelven). stackoverflow.com, 2009. február 11. (Hozzáférés: 2012. július 5.)
  7. Immutabale Atomic Value Type (angol nyelven) (pdf). Effective C#. (Hozzáférés: 2012. július 5.)

Külső hivatkozások[szerkesztés | forrásszöveg szerkesztése]