Operatoren voor typetests en cast-expressies - is
, as
typeof
en cast-expressies
Deze operators en expressies voeren typecontrole of typeconversie uit. De is
operator controleert of het runtimetype van een expressie compatibel is met een bepaald type. De as
operator converteert expliciet een expressie naar een bepaald type als het runtimetype compatibel is met dat type. Cast-expressies voeren een expliciete conversie uit naar een doeltype. De typeof
operator verkrijgt het System.Type exemplaar voor een type.
is operator
De is
operator controleert of het uitvoeringstype van een expressieresultaat compatibel is met een bepaald type. De is
operator test ook een expressieresultaat op basis van een patroon.
De expressie met de operator voor typetests is
heeft het volgende formulier
E is T
waarbij E
een expressie een waarde retourneert en T
de naam is van een type of een typeparameter. E
kan geen anonieme methode of lambda-expressie zijn.
De is
operator retourneert true
wanneer een expressieresultaat niet null is en een van de volgende voorwaarden waar is:
Het uitvoeringstype van een expressieresultaat is
T
.Het uitvoeringstype van een expressieresultaat is afgeleid van het type
T
, implementeert interfaceT
of een andere impliciete verwijzingsconversie bestaat van daaruitT
.Het uitvoeringstype van een expressieresultaat is een null-waardetype met het onderliggende type
T
en het Nullable<T>.HasValue istrue
.Er bestaat een conversie van boksen of het uitboxen van het uitvoeringstype van een expressieresultaat dat moet worden getypt
T
.
De is
operator houdt geen rekening met door de gebruiker gedefinieerde conversies.
In het volgende voorbeeld ziet u dat de is
operator retourneert true
als het uitvoeringstijdtype van een expressieresultaat is afgeleid van een bepaald type, dat wil gezegd, er een verwijzingsconversie bestaat tussen typen:
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
}
}
In het volgende voorbeeld ziet u dat de is
operator rekening houdt met conversies voor boksen en het opheffen van vakken, maar geen rekening houdt met numerieke conversies:
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
Zie het hoofdstuk Conversies van de C#-taalspecificatie voor meer informatie over C#-conversies.
Typetests met patroonkoppeling
De is
operator test ook een expressieresultaat op basis van een patroon. In het volgende voorbeeld ziet u hoe u een declaratiepatroon gebruikt om het uitvoeringstype van een expressie te controleren:
int i = 23;
object iBoxed = i;
int? jNullable = 7;
if (iBoxed is int a && jNullable is int b)
{
Console.WriteLine(a + b); // output 30
}
Zie Patronen voor meer informatie over de ondersteunde patronen.
as-operator
De as
operator converteert het resultaat van een expressie expliciet naar een bepaald verwijzings- of null-waardetype. Als de conversie niet mogelijk is, retourneert null
de as
operator . In tegenstelling tot een cast-expressie genereert de as
operator nooit een uitzondering.
De expressie van het formulier
E as T
waar E
is een expressie die een waarde retourneert en T
de naam van een type of een typeparameter is, produceert hetzelfde resultaat als
E is T ? (T)(E) : (T)null
behalve dat dit E
slechts eenmaal wordt geëvalueerd.
De as
operator beschouwt alleen verwijzings-, null-, boks- en uitboxingconversies. U kunt de operator niet gebruiken om een door de as
gebruiker gedefinieerde conversie uit te voeren. Gebruik hiervoor een cast-expressie.
In het volgende voorbeeld ziet u het gebruik van de as
operator:
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
}
Notitie
Zoals in het voorgaande voorbeeld wordt weergegeven, moet u het resultaat van de as
expressie null
vergelijken om te controleren of de conversie is geslaagd. U kunt de operator is beide gebruiken om te testen of de conversie slaagt en, als deze slaagt, het resultaat toe te wijzen aan een nieuwe variabele.
Cast-expressie
Een cast-expressie van het formulier (T)E
voert een expliciete conversie uit van het resultaat van de expressie E
die moet worden getypt T
. Als er geen expliciete conversie bestaat van het type E
naar type T
, treedt er een compilatietijdfout op. Tijdens runtime slaagt een expliciete conversie mogelijk niet en kan een cast-expressie een uitzondering genereren.
In het volgende voorbeeld ziet u expliciete numerieke en verwijzingsconversies:
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
Zie de sectie Expliciete conversies van de C#-taalspecificatie voor informatie over ondersteunde expliciete conversies. Zie Door de gebruiker gedefinieerde conversies voor meer informatie over het definiëren van een aangepaste expliciete of impliciete typeconversie.
Andere gebruiksrechten van ()
U gebruikt ook haakjes om een methode aan te roepen of een gemachtigde aan te roepen.
Een ander gebruik van haakjes is het aanpassen van de volgorde waarin bewerkingen in een expressie moeten worden geëvalueerd. Zie C#-operators voor meer informatie.
typeof-operator
De typeof
operator verkrijgt het System.Type exemplaar voor een type. Het argument voor de typeof
operator moet de naam van een type of een typeparameter zijn, zoals in het volgende voorbeeld wordt weergegeven:
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]
Het argument mag geen type zijn waarvoor metagegevensaantekeningen zijn vereist. Voorbeelden zijn de volgende typen:
dynamic
string?
(of een null-verwijzingstype)
Deze typen worden niet rechtstreeks weergegeven in metagegevens. De typen bevatten kenmerken die het onderliggende type beschrijven. In beide gevallen kunt u het onderliggende type gebruiken. In plaats van dynamic
, kunt u gebruiken object
. In plaats van string?
, kunt u gebruiken string
.
U kunt de typeof
operator ook gebruiken met niet-afhankelijke algemene typen. De naam van een niet-afhankelijk algemeen type moet het juiste aantal komma's bevatten, dat één kleiner is dan het aantal typeparameters. In het volgende voorbeeld ziet u het gebruik van de typeof
operator met een niet-afhankelijk algemeen type:
Console.WriteLine(typeof(Dictionary<,>));
// Output:
// System.Collections.Generic.Dictionary`2[TKey,TValue]
Een expressie kan geen argument van de typeof
operator zijn. Gebruik de Object.GetType methode om het System.Type exemplaar op te halen voor het uitvoeringstype van een expressieresultaat.
Typetests met de typeof
operator
Gebruik de typeof
operator om te controleren of het uitvoeringstype van het expressieresultaat exact overeenkomt met een bepaald type. In het volgende voorbeeld ziet u het verschil tussen het controleren van het type dat is uitgevoerd met de typeof
operator en de operator 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
}
}
Overbelasting van operatoren
De is
, as
en typeof
operators kunnen niet worden overbelast.
Een door de gebruiker gedefinieerd type kan de ()
operator niet overbelasten, maar kan aangepaste typeconversies definiëren die kunnen worden uitgevoerd door een cast-expressie. Zie Door de gebruiker gedefinieerde conversieoperators voor meer informatie.
C#-taalspecificatie
Zie de volgende secties van de C#-taalspecificatie voor meer informatie: