Přetypování a převody typů (Průvodce programováním v C#)

Vzhledem k tomu, že jazyk C# je staticky napsaný v době kompilace, nelze po deklaraci proměnné znovu deklarovat ani přiřadit hodnotu jiného typu, pokud tento typ není implicitně převoditelný na typ proměnné. string Například nelze implicitně převést na int. Proto poté, co deklarujete i jako , intnemůžete přiřadit řetězec "Hello" k němu, jak ukazuje následující kód:

int i;

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

Někdy ale budete muset zkopírovat hodnotu do proměnné nebo parametru metody jiného typu. Můžete mít například celočíselnou proměnnou, kterou potřebujete předat metodě, jejíž parametr je zadán jako double. Nebo možná budete muset přiřadit proměnnou třídy proměnné typu rozhraní. Tyto druhy operací se nazývají převody typů. V jazyce C# můžete provádět následující druhy převodů:

  • Implicitní převody: Nevyžaduje se žádná zvláštní syntaxe, protože převod vždy proběhne úspěšně a nedojde ke ztrátě dat. Mezi příklady patří převody z menších na větší celočíselné typy a převody z odvozených tříd na základní třídy.

  • Explicitní převody (přetypování):Explicitní převody vyžadují výraz přetypování. Přetypování je vyžadováno, pokud mohou být informace v převodu ztraceny nebo pokud převod nemusí být úspěšný z jiných důvodů. Mezi typické příklady patří číselný převod na typ, který má menší přesnost nebo menší rozsah, a převod instance základní třídy na odvozenou třídu.

  • Převody definované uživatelem: Převody definované uživatelem používají speciální metody, které můžete definovat, aby bylo možné povolit explicitní a implicitní převody mezi vlastními typy, které nemají relaci základní třídy odvozené od třídy. Další informace naleznete v tématu Uživatelem definované operátory převodu.

  • Převody s pomocnými třídami: K převodu mezi nekompatibilními typy, jako jsou celá čísla a System.DateTime objekty nebo šestnáctkové řetězce a bajtová pole, můžete použít System.BitConverter třídu, System.Convert třídu a Parse metody předdefinovaných číselných typů, například Int32.Parse. Další informace naleznete v tématu Jak převést bajtové pole na int, Jak převést řetězec na číslo a Jak převést mezi šestnáctkovými řetězci a číselnými typy.

Implicitní převody

U předdefinovaných číselných typů lze implicitní převod provést, když se hodnota, která se má uložit, vejde do proměnné bez zkrácení nebo zaokrouhlení. U integrálních typů to znamená, že rozsah zdrojového typu je správná podmnožina rozsahu pro cílový typ. Například proměnná typu long (64bitové celé číslo) může ukládat libovolnou hodnotu, kterou může uložit int (32bitové celé číslo). V následujícím příkladu kompilátor implicitně převede hodnotu num vpravo na typ long před jeho přiřazením .bigNum

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

Úplný seznam všech implicitních číselných převodů najdete v části Implicitní číselné převody v článku Předdefinované číselné převody.

U referenčních typů implicitní převod vždy existuje z třídy na libovolnou z jejích přímých nebo nepřímých základních tříd nebo rozhraní. Není nutná žádná speciální syntaxe, protože odvozená třída vždy obsahuje všechny členy základní třídy.

Derived d = new Derived();

// Always OK.
Base b = d;

Explicitní převody

Pokud však převod nelze provést bez rizika ztráty informací, kompilátor vyžaduje, abyste provedli explicitní převod, který se nazývá přetypování. Přetypování je způsob, jak explicitně informovat kompilátor, že máte v úmyslu provést převod a že může dojít ke ztrátě dat nebo může dojít k selhání přetypování za běhu. Chcete-li provést přetypování, zadejte typ přetypování do závorek před hodnotou nebo proměnnou, kterou chcete převést. Následující program přetypuje dvojitou na int. Program se nezkompiluje bez přetypování.

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

Úplný seznam podporovaných explicitních číselných převodů najdete v části Explicitní číselné převody v článku Předdefinované číselné převody.

Pro odkazové typy je vyžadováno explicitní přetypování, pokud potřebujete převést ze základního typu na odvozený typ:

// 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;

Operace přetypování mezi odkazovými typy nemění typ běhu základního objektu; změní pouze typ hodnoty, která se používá jako odkaz na tento objekt. Další informace naleznete v tématu Polymorfismus.

Výjimky převodu typů za běhu

V některých převodech typu odkazu kompilátor nemůže určit, zda je přetypování platné. Je možné, že operace přetypování, která se správně zkompiluje, selže za běhu. Jak je znázorněno v následujícím příkladu, přetypování typu, které v době běhu selže, způsobí InvalidCastException vyvolání.

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;
    }
}

Metoda TestAnimal parametr, a proto explicitně přetypuje argument a na Reptile nebezpečný předpoklad. Je bezpečnější nedělit předpoklady, ale raději zkontrolovat typ. Jazyk C# poskytuje operátor, který umožňuje otestovat kompatibilitu před provedením přetypování. Další informace najdete v tématu Bezpečné přetypování pomocí porovnávání vzorů a operátorů a operátorů.

specifikace jazyka C#

Další informace najdete v části Převody specifikace jazyka C#.

Viz také