Casting and type conversions (C# programozási útmutató)

Mivel a C# statikusan van beírva fordításkor, a változó deklarálása után nem deklarálható újra, és nem rendelhető hozzá más típusú értékhez, kivéve, ha ez a típus implicit módon átalakítható a változó típusára. A program például string nem konvertálható implicit módon int. Ezért a deklarálás iintután nem rendelheti hozzá a "Hello" sztringet, ahogy az alábbi kód is mutatja:

int i;

// error CS0029: can't implicitly convert type 'string' to 'int'
i = "Hello";

Előfordulhat azonban, hogy egy értéket másolnia kell egy másik típusú változóba vagy metódusparaméterbe. Előfordulhat például, hogy van egy egész szám változója, amelyet át kell adnia egy metódusnak, amelynek paramétere a következő.double Vagy előfordulhat, hogy osztályváltozót kell hozzárendelnie egy felülettípusú változóhoz. Ezeket a műveleteket típuskonverziónak nevezzük. A C#-ban a következő típusú átalakításokat hajthatja végre:

  • Implicit konverziók: Nincs szükség speciális szintaxisra, mert az átalakítás mindig sikeres, és nem vesznek el adatok. Ilyenek például a kisebb és a nagyobb integrált típusok közötti átalakítások, valamint a származtatott osztályokból alaposztályokké történő átalakítások.

  • Explicit konverziók (öntöttek):: Az explicit konverziókhoz öntött kifejezésre van szükség. Az átalakításra akkor van szükség, ha az adatok elveszhetnek az átalakítás során, vagy ha az átalakítás más okból nem sikerül. Tipikus példák például a numerikus átalakítás kisebb pontosságú vagy kisebb tartományú típusra, valamint az alaposztálypéldányok származtatott osztályba való konvertálása.

  • Felhasználó által definiált konverziók: A felhasználó által definiált konverziók speciális metódusokat használnak, amelyekkel explicit és implicit konverziókat engedélyezhet olyan egyéni típusok között, amelyek nem rendelkeznek alaposztály-származtatott osztálykapcsolatokkal. További információ: Felhasználó által definiált konverziós operátorok.

  • Konverziók segédosztályokkal: Nem kompatibilis típusok, például egész számok és System.DateTime objektumok, hexadecimális sztringek és bájttömbök közötti konvertáláshoz használhatja az System.BitConverter osztályt, az System.Convert osztályt és a Parse beépített numerikus típusok metódusait, például Int32.Parse. További információ : Bájttömb átalakítása intsé, sztring átalakítása számmá, és hogyan konvertálható hexadecimális sztringek és numerikus típusok között.

Implicit konverziók

A beépített numerikus típusok esetében implicit átalakítást lehet elvégezni, ha a tárolandó érték csonkítás vagy lekerekítés nélkül illeszkedik a változóba. Az integráltípusok esetében ez azt jelenti, hogy a forrástípus tartománya a céltípus tartományának megfelelő részhalmaza. Egy hosszú típusú változó (64 bites egész szám) például bármilyen értéket tárolhat, amelyet egy int (32 bites egész szám) tárolhat. Az alábbi példában a fordító implicit módon átalakítja a jobb oldali értéket num egy típussá long , mielőtt hozzá rendeli bigNum.

// Implicit conversion. A long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;

Az összes implicit numerikus konverzió teljes listáját a beépített numerikus konverziók cikk implicit numerikus konverziók szakaszában találja.

Referenciatípusok esetén az implicit átalakítás mindig létezik egy osztályból bármely közvetlen vagy közvetett alaposztályba vagy interfészbe. Nincs szükség speciális szintaxisra, mert egy származtatott osztály mindig tartalmazza az alaposztály összes tagját.

Derived d = new Derived();

// Always OK.
Base b = d;

Explicit konverziók

Ha azonban a konvertálás nem végezhető el az adatok elvesztésének kockázata nélkül, a fordítónak explicit átalakítást kell végrehajtania, amelyet stábnak nevezünk. A leadással explicit módon tájékoztathatja a fordítót arról, hogy meg szeretné tenni az átalakítást, és tisztában van azzal, hogy adatvesztés történhet, vagy a leadás futásidőben meghiúsulhat. A leadást úgy hajthatja végre, hogy a konvertálandó érték vagy változó előtt zárójelben adja meg a típust. Az alábbi program egy dupla elemet ad egy inthez. A program nem fordítja le a szereplők nélkül.

class Test
{
    static void Main()
    {
        double x = 1234.7;
        int a;
        // Cast double to int.
        a = (int)x;
        System.Console.WriteLine(a);
    }
}
// Output: 1234

A támogatott explicit numerikus konverziók teljes listáját a beépített numerikus átalakítások cikk Explicit numerikus konverziók szakaszában találja.

Referenciatípusok esetén explicit leadáshoz van szükség, ha alaptípusból származtatott típusra kell konvertálnia:

// Create a new derived type.
Giraffe g = new Giraffe();

// Implicit conversion to base type is safe.
Animal a = g;

// Explicit conversion is required to cast back
// to derived type. Note: This will compile but will
// throw an exception at run time if the right-side
// object is not in fact a Giraffe.
Giraffe g2 = (Giraffe)a;

A referenciatípusok közötti öntött művelet nem módosítja az alapul szolgáló objektum futásidejének típusát; csak az adott objektumra mutató hivatkozásként használt érték típusát módosítja. További információ: Polimorfizmus.

Típuskonvertálási kivételek futásidőben

Bizonyos referenciatípus-átalakítások esetén a fordító nem tudja megállapítani, hogy érvényes-e a leadás. Futtatáskor előfordulhat, hogy a helyesen lefordított öntött művelet meghiúsul. Ahogy az a következő példában is látható, a futtatáskor meghiúsuló típus leadása dobást okoz InvalidCastException .

class Animal
{
    public void Eat() => System.Console.WriteLine("Eating.");

    public override string ToString() => "I am an animal.";
}

class Reptile : Animal { }
class Mammal : Animal { }

class UnSafeCast
{
    static void Main()
    {
        Test(new Mammal());

        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }

    static void Test(Animal a)
    {
        // System.InvalidCastException at run time
        // Unable to cast object of type 'Mammal' to type 'Reptile'
        Reptile r = (Reptile)a;
    }
}

A Test metódus paraméterrel Animal rendelkezik, így az argumentumot a kifejezetten veszélyes feltételezésnek Reptile veti ki. Biztonságosabb, ha nem feltételezünk feltételezéseket, hanem inkább ellenőrizzük a típust. A C# lehetővé teszi az operátor számára, hogy tesztelje a kompatibilitást, mielőtt ténylegesen végrehajtanál egy leadást. További információ: Hogyan lehet biztonságosan leadni a mintaegyeztetés és az as és az is operátorok használatával.

C# nyelvspecifikáció

További információ: A C# nyelv specifikációjának Konverziók szakasza.

Lásd még