Sdílet prostřednictvím


Operátory testování typů a přetypování výrazů - is, as, typeof a přetypování výrazů

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

Referenční dokumentace jazyka C# dokumentuje naposledy vydané verze jazyka C#. Obsahuje také počáteční dokumentaci k funkcím ve verzi Public Preview pro nadcházející jazykovou verzi.

Dokumentace identifikuje všechny funkce, které byly poprvé představeny v posledních třech verzích jazyka nebo v aktuálních verzích Public Preview.

Návod

Informace o tom, kdy byla funkce poprvé představena v jazyce C#, najdete v článku o historii verzí jazyka C#.

Operátor is

Operátor is zkontroluje, jestli je typ běhu výsledku výrazu kompatibilní s daným typem. Operátor is také testuje výsledek výrazu vůči vzoru.

Výraz s operátorem testování is typu má následující formulář.

E is T

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

Operátor is vrátí true , když je výsledek výrazu nenulový a platí některé z následujících podmínek:

  • Typ běhu výsledku výrazu má převod identity na T.

  • Typ běhu výsledku výrazu je odvozen od typu T, implementuje rozhraní Tnebo jiný implicitní převod odkazu existuje z něj .T Tato podmínka zahrnuje vztahy dědičnosti a implementace rozhraní.

  • Typ běhu výsledku výrazu je typ hodnoty null s podkladovým typem T a Nullable<T>.HasValue je true.

  • Boxování nebo unboxování existuje z běhového typu výsledku výrazu na typ T, pokud výraz není instancí ref struct.

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

Následující příklad ukazuje, že is operátor vrátí true , pokud typ běhu výsledku výrazu je odvozen z daného typu, to znamená, že existuje odkaz převodu 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 boxingu a rozbalování, ale nepovažuje za čí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# naleznete v kapitole Převody specifikace jazyka C#.

Testování typů s odpovídajícími vzory

Operátor is také testuje výsledek výrazu vůči vzoru. Následující příklad ukazuje, jak pomocí vzoru deklarace zkontrolovat typ 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ýchvzorch

Operátor as

Pomocí operátoru as explicitně převeďte výsledek výrazu na daný odkaz nebo typ hodnoty s možnou hodnotou null. Pokud převod není možný, as vrátí nulloperátor . Na rozdíl od výrazu as př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, vytvoří stejný výsledek jako

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

Kromě toho, že E se vyhodnotí jenom 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í uživatelem definovaného převodu. K provedení uživatelem definovaného převodu použijte výraz přetypování.

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

IEnumerable<int> numbers = new List<int>(){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 aby bylo ověřeno, zda byl převod úspěšný. Operátor můžete použít is k otestování, jestli převod proběhne úspěšně, a pokud bude úspěšný, přiřaďte jeho výsledek k nové proměnné.

Přetypování výrazu

Výraz přetypování formuláře (T)E explicitně převede výsledek výrazu E na typ T. Pokud neexistuje explicitní převod z typu E na typ T, kompilátor vydá chybu. V době běhu nemusí explicitní převod proběhnout ú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

int[] ints = [10, 20, 30];
IEnumerable<int> numbers = ints;
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řevody specifikace jazyka C#. Informace o tom, jak definovat vlastní explicitní nebo implicitní převod typu, naleznete v tématu Uživatelem definované převodní operátory.

Další využ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 jazyk C# vyhodnocuje operace ve výrazu. Další informace najdete v tématu Operátory jazyka C#.

Operátor typeof

Operátor typeof získá System.Type instanci pro typ. Argument operátoru typeof musí být název typu nebo parametru 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 nemůže být typem, který vyžaduje poznámky metadat. Mezi příklady těchto typů patří následující typy:

  • dynamic
  • string? (nebo jakýkoli typ odkazu 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 dynamic použijte object. Místo string? použijte string.

Operátor můžete použít typeof také 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 jedna menší 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 typů provedenou pomocí typeof operátoru a operátoruis:

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

Nemůžete přetížit operátory is, asa typeof operátory.

Uživatelem definovaný typ nemůže přetížit () operátor, ale může definovat vlastní převody typů, které výraz přetypování provádí. Další informace naleznete 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é