Operátory testování typů a výrazy přetypování – is, astypeof a přetypování

Tyto operátory a výrazy provádějí kontrolu typů nebo převod typů. Operátoris zkontroluje, jestli je typ výrazu za běhu kompatibilní s daným typem. Operátoras explicitně převede výraz na daný typ, pokud je jeho typ za běhu kompatibilní s tímto typem. Výrazy přetypování provádějí explicitní převod na cílový typ. Operátor typeof získáSystem.Type instanci pro typ.

is – operátor

Operátor is zkontroluje, jestli je typ za běhu výsledku výrazu kompatibilní s daným typem. Operátor is také testuje výsledek výrazu se vzorem.

Výraz s operátorem testování is typů má následující tvar.

E is T

where E je výraz, který vrací hodnotu a T je názvem typu nebo parametru typu. E nemůže být anonymní metoda ani výraz lambda.

Operátor is vrátí true , pokud výsledek výrazu není null a platí některá z následujících podmínek:

Operátor is nebere v úvahu převody definované uživatelem.

Následující příklad ukazuje, že is operátor vrátí true , pokud typ za běhu výsledku výrazu je odvozen od daného typu, to znamená, že existuje převod odkazů mezi typy:

public class Base { }

public class Derived : Base { }

public static class IsOperatorExample
{
    public static void Main()
    {
        object b = new Base();
        Console.WriteLine(b is Base);  // output: True
        Console.WriteLine(b is Derived);  // output: False

        object d = new Derived();
        Console.WriteLine(d is Base);  // output: True
        Console.WriteLine(d is Derived); // output: True
    }
}

Další příklad ukazuje, že is operátor bere v úvahu převody při balení a rozbalování, ale nebere v úvahu číselné převody:

int i = 27;
Console.WriteLine(i is System.IFormattable);  // output: True

object iBoxed = i;
Console.WriteLine(iBoxed is int);  // output: True
Console.WriteLine(iBoxed is long);  // output: False

Informace o převodech jazyka C# najdete v kapitole Převodyspecifikace jazyka C#.

Testování typů pomocí porovnávání vzorů

Operátor is také testuje výsledek výrazu se vzorem. Následující příklad ukazuje, jak použít vzor deklarace ke kontrole typu za běhu výrazu:

int i = 23;
object iBoxed = i;
int? jNullable = 7;
if (iBoxed is int a && jNullable is int b)
{
    Console.WriteLine(a + b);  // output 30
}

Informace o podporovaných vzorech najdete v tématu Vzory.

Operátor as

Operátor as explicitně převede výsledek výrazu na daný odkaz nebo typ hodnoty s možnou hodnotou null. Pokud převod není možný, as operátor vrátí null. Na rozdíl od výrazu aspřetypování operátor nikdy nevyvolá výjimku.

Výraz formuláře

E as T

kde E je výraz, který vrací hodnotu a T je názvem typu nebo parametru typu, vygeneruje stejný výsledek jako

E is T ? (T)(E) : (T)null

kromě toho, že se E vyhodnocuje pouze jednou.

Operátor as bere v úvahu pouze převody odkaz, s možnou hodnotou null, boxing a unboxing. Operátor nelze použít as k provedení převodu definovaného uživatelem. K tomu použijte výraz přetypování.

Následující příklad ukazuje použití operátoru as :

IEnumerable<int> numbers = new[] { 10, 20, 30 };
IList<int> indexable = numbers as IList<int>;
if (indexable != null)
{
    Console.WriteLine(indexable[0] + indexable[indexable.Count - 1]);  // output: 40
}

Poznámka

Jak ukazuje předchozí příklad, musíte porovnat výsledek výrazu as s , null abyste zkontrolovali, jestli byl převod úspěšný. Operátor is můžete použít k otestování úspěšného převodu a v případě úspěchu přiřazení výsledku k nové proměnné.

Výraz přetypování

Výraz přetypování formuláře (T)E provádí explicitní převod výsledku výrazu E na typ T. Pokud neexistuje explicitní převod z typu E na typ T, dojde k chybě kompilace. Za běhu nemusí být explicitní převod úspěšný a výraz přetypování může vyvolat výjimku.

Následující příklad ukazuje explicitní číselné a referenční převody:

double x = 1234.7;
int a = (int)x;
Console.WriteLine(a);   // output: 1234

IEnumerable<int> numbers = new int[] { 10, 20, 30 };
IList<int> list = (IList<int>)numbers;
Console.WriteLine(list.Count);  // output: 3
Console.WriteLine(list[1]);  // output: 20

Informace o podporovaných explicitních převodech najdete v části Explicitní převodyspecifikace jazyka C#. Informace o tom, jak definovat vlastní explicitní nebo implicitní převod typu, najdete v tématu Operátory převodu definované uživatelem.

Další použití ()

Pomocí závorek můžete také volat metodu nebo vyvolat delegáta.

Dalším použitím závorek je úprava pořadí, ve kterém se mají vyhodnocovat operace ve výrazu. Další informace najdete v tématu Operátory jazyka C#.

typeof – operátor

Operátor typeof získá System.Type instanci pro typ. Argumentem operátoru typeof musí být název typu nebo parametr typu, jak ukazuje následující příklad:

void PrintType<T>() => Console.WriteLine(typeof(T));

Console.WriteLine(typeof(List<string>));
PrintType<int>();
PrintType<System.Int32>();
PrintType<Dictionary<int, char>>();
// Output:
// System.Collections.Generic.List`1[System.String]
// System.Int32
// System.Int32
// System.Collections.Generic.Dictionary`2[System.Int32,System.Char]

Argument nesmí být typ, který vyžaduje poznámky metadat. Mezi příklady patří následující typy:

  • dynamic
  • string? (nebo jakýkoli odkaz s možnou hodnotou null)

Tyto typy nejsou přímo reprezentovány v metadatech. Typy zahrnují atributy, které popisují základní typ. V obou případech můžete použít základní typ. Místo můžete dynamicpoužít object. Místo můžete string?použít string.

Můžete také použít typeof operátor s nevázanými obecnými typy. Název nevázaného obecného typu musí obsahovat odpovídající počet čárek, což je o jednu méně než počet parametrů typu. Následující příklad ukazuje použití operátoru typeof s nevázaným obecným typem:

Console.WriteLine(typeof(Dictionary<,>));
// Output:
// System.Collections.Generic.Dictionary`2[TKey,TValue]

Výraz nemůže být argumentem operátoru typeof . Pokud chcete získat System.Type instanci pro typ běhu výsledku výrazu, použijte metodu Object.GetType .

Testování typů pomocí operátoru typeof

Pomocí operátoru typeof zkontrolujte, jestli typ běhu výsledku výrazu přesně odpovídá danému typu. Následující příklad ukazuje rozdíl mezi kontrolou typu provedenou pomocí operátoru typeof a operátorem is:

public class Animal { }

public class Giraffe : Animal { }

public static class TypeOfExample
{
    public static void Main()
    {
        object b = new Giraffe();
        Console.WriteLine(b is Animal);  // output: True
        Console.WriteLine(b.GetType() == typeof(Animal));  // output: False

        Console.WriteLine(b is Giraffe);  // output: True
        Console.WriteLine(b.GetType() == typeof(Giraffe));  // output: True
    }
}

Přetížení operátoru

Operátory is, asa typeof nelze přetížit.

Uživatelem definovaný typ nemůže přetížit () operátor, ale může definovat vlastní převody typů, které lze provádět výrazem přetypování. Další informace najdete v tématu Uživatelem definované operátory převodu.

specifikace jazyka C#

Další informace najdete v následujících částech specifikace jazyka C#:

Viz také