Operatory testowania typów i wyrażenia rzutowane — is
, typeof
as
i 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 interfejsT
lub inną niejawną konwersję odwołania istnieje z niego doT
.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. dynamic
Zamiast 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
, as
i 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#: