Operatory testowania typów i wyrażenia rzutowane — is, typeofasi rzutowane

Te operatory i wyrażenia wykonują sprawdzanie typów lub konwersję typów. Operator is sprawdza, czy typ czasu wykonywania wyrażenia jest zgodny z danym typem. Operator as jawnie konwertuje wyrażenie na dany typ, jeśli jego typ czasu wykonywania jest zgodny z tym typem. Wyrażenia rzutowania wykonują jawną konwersję na typ docelowy. Operator typeof uzyskuje System.Type wystąpienie typu.

operator is

Operator is sprawdza, czy typ czasu wykonywania wyniku wyrażenia jest zgodny z danym typem. Operator is testuje również wynik wyrażenia względem wzorca.

Wyrażenie z operatorem testowania is typów ma następujący formularz

E is T

gdzie E jest wyrażeniem, które zwraca wartość i T jest nazwą typu lub parametru typu. E nie może być metodą anonimową ani wyrażeniem lambda.

Operator is zwraca true wartość, gdy wynik wyrażenia ma wartość inną niż null, a wszystkie z następujących warunków są spełnione:

  • Typ czasu wykonywania wyniku wyrażenia to T.

  • Typ czasu wykonywania wyniku wyrażenia pochodzi z typu T, implementuje interfejs Tlub inną niejawną konwersję odwołania istnieje z niego do T.

  • Typ czasu wykonywania wyniku wyrażenia jest typem wartości dopuszczanej do wartości null z typem T bazowym i ma Nullable<T>.HasValue wartość true.

  • Konwersja boksu lub rozpasania istnieje z typu czasu wykonywania wyniku wyrażenia na typ T.

Operator is nie uwzględnia konwersji zdefiniowanych przez użytkownika.

W poniższym przykładzie pokazano, że operator zwracatrue, is jeśli typ czasu wykonywania wyniku wyrażenia pochodzi z danego typu, czyli istnieje konwersja referencyjna między typami:

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

W następnym przykładzie is pokazano, że operator uwzględnia konwersje boksu i rozpakowy, ale nie uwzględnia konwersji liczbowych:

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

Aby uzyskać informacje na temat konwersji języka C#, zobacz rozdział Konwersje specyfikacji języka C#.

Testowanie typów z dopasowaniem wzorca

Operator is testuje również wynik wyrażenia względem wzorca. W poniższym przykładzie pokazano, jak za pomocą wzorca deklaracji sprawdzić typ czasu wykonywania wyrażenia:

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

Aby uzyskać informacje o obsługiwanych wzorcach, zobacz Wzorce.

operator as

Operator as jawnie konwertuje wynik wyrażenia na dany typ wartości referencyjnej lub dopuszczanej do wartości null. Jeśli konwersja nie jest możliwa, as operator zwraca wartość null. W przeciwieństwie do wyrażeniaas rzutowania, operator nigdy nie zgłasza wyjątku.

Wyrażenie formularza

E as T

gdzie E jest wyrażeniem, które zwraca wartość i T jest nazwą typu lub parametru typu, generuje ten sam wynik co

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

z wyjątkiem tego, że E jest obliczany tylko raz.

Operator as uwzględnia tylko konwersje odwołań, dopuszczających wartości null, boxing i rozpakowywalnych. Nie można użyć as operatora do przeprowadzenia konwersji zdefiniowanej przez użytkownika. W tym celu użyj wyrażenia rzutowania.

W poniższym przykładzie pokazano użycie as operatora:

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
}

Uwaga

Jak pokazano w poprzednim przykładzie, należy porównać wynik as wyrażenia z null , aby sprawdzić, czy konwersja zakończyła się pomyślnie. Możesz użyć operatora is, aby przetestować, czy konwersja zakończy się pomyślnie, a jeśli zakończy się pomyślnie, przypisz jego wynik do nowej zmiennej.

Wyrażenie rzutu

Wyrażenie rzutowania formularza (T)E wykonuje jawną konwersję wyniku wyrażenia E na typ T. Jeśli nie istnieje jawna konwersja typu E na typ T, wystąpi błąd czasu kompilacji. W czasie wykonywania jawna konwersja może się nie powieść, a wyrażenie rzutowe może zgłosić wyjątek.

W poniższym przykładzie pokazano jawne konwersje liczbowe i referencyjne:

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

Aby uzyskać informacje na temat obsługiwanych konwersji jawnych, zobacz sekcję Jawne konwersje specyfikacji języka C#. Aby uzyskać informacje o sposobie definiowania niestandardowej jawnej lub niejawnej konwersji typu, zobacz Operatory konwersji zdefiniowane przez użytkownika.

Inne zastosowania ()

Nawiasy służą również do wywoływania metody lub wywoływania delegata.

Innym zastosowaniem nawiasów jest dostosowanie kolejności, w jakiej mają być obliczane operacje w wyrażeniu. Aby uzyskać więcej informacji, zobacz Operatory języka C#.

typeof — Operator

Operator typeof uzyskuje System.Type wystąpienie typu. Argument typeof operatora musi być nazwą typu lub parametru typu, jak pokazano w poniższym przykładzie:

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 nie może być typem, który wymaga adnotacji metadanych. Przykłady obejmują następujące typy:

  • dynamic
  • string? (lub dowolny typ odwołania dopuszczalny do wartości null)

Te typy nie są bezpośrednio reprezentowane w metadanych. Typy zawierają atrybuty opisujące typ bazowy. W obu przypadkach można użyć typu bazowego. dynamicZamiast programu można użyć polecenia object. string?Zamiast programu można użyć polecenia string.

Możesz również użyć typeof operatora z niezwiązanymi typami ogólnymi. Nazwa niezwiązanego typu ogólnego musi zawierać odpowiednią liczbę przecinków, która jest mniejsza niż liczba parametrów typu. W poniższym przykładzie pokazano użycie typeof operatora z niezwiązanym typem ogólnym:

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

Wyrażenie nie może być argumentem typeof operatora. Aby uzyskać System.Type wystąpienie dla typu czasu wykonywania wyniku wyrażenia, użyj Object.GetType metody .

Testowanie typów za pomocą typeof operatora

typeof Użyj operatora , aby sprawdzić, czy typ czasu wykonywania wyniku wyrażenia dokładnie pasuje do danego typu. W poniższym przykładzie pokazano różnicę między sprawdzaniem typu wykonanym z operatorem typeof a operatorem 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
    }
}

Przeciążenie operatora

Operatory is, asi typeof nie mogą być przeciążone.

Typ zdefiniowany przez użytkownika nie może przeciążyć () operatora, ale może definiować konwersje typów niestandardowych, które mogą być wykonywane przez wyrażenie rzutowania. Aby uzyskać więcej informacji, zobacz Operatory konwersji zdefiniowane przez użytkownika.

specyfikacja języka C#

Aby uzyskać więcej informacji, zobacz następujące sekcje specyfikacji języka C#:

Zobacz też