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.

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 Týká se to vztahů dědičnosti a implementací 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

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 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 tomu 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 provádí explicitní převod výsledku výrazu E na typ T. Pokud neexistuje žádný explicitní převod z typu E na typ T, dojde k chybě v době kompilace. 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 se mají vyhodnocovat 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 nesmí být typem, který vyžaduje poznámky metadat. Mezi příklady 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. dynamicMísto , můžete použít object. string?Místo , můžete použít 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 operátorem 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 a operátory isnelze astypeof přetížit.

Uživatelem definovaný typ nemůže přetížit () operátor, ale může definovat vlastní převody typů pomocí výrazu pro přetypování. 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é