Typtestningsoperatorer och cast-uttryck – is
, as
typeof
och casts
Dessa operatorer och uttryck utför typkontroll eller typkonvertering. Operatorn is
kontrollerar om körningstypen för ett uttryck är kompatibel med en viss typ. Operatorn as
konverterar uttryckligen ett uttryck till en viss typ om dess körningstyp är kompatibel med den typen. Cast-uttryck utför en explicit konvertering till en måltyp. Operatorn typeof
hämtar instansen System.Type för en typ.
är operator
Operatorn is
kontrollerar om körningstypen för ett uttrycksresultat är kompatibel med en viss typ. Operatorn is
testar också ett uttrycksresultat mot ett mönster.
Uttrycket med typtestningsoperatorn is
har följande formulär
E is T
där E
är ett uttryck som returnerar ett värde och T
är namnet på en typ eller en typparameter. E
får inte vara en anonym metod eller ett lambda-uttryck.
Operatorn is
returnerar true
när ett uttrycksresultat inte är null och något av följande villkor är sant:
Körningstypen för ett uttrycksresultat är
T
.Körningstypen för ett uttrycksresultat härleds från typen
T
, implementerar gränssnittetT
eller så finns det en annan implicit referenskonvertering från den tillT
.Körningstypen för ett uttrycksresultat är en nullbar värdetyp med den underliggande typen
T
och Nullable<T>.HasValue ärtrue
.En boxnings - eller avboxningskonvertering finns från körningstypen för ett uttrycksresultat för att skriva
T
.
Operatorn is
överväger inte användardefinierade konverteringar.
Följande exempel visar att operatorn is
returnerar true
om körningstypen för ett uttrycksresultat härleds från en viss typ, det vill säga att det finns en referenskonvertering mellan typer:
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
}
}
Nästa exempel visar att operatorn is
tar hänsyn till boxnings- och avboxningskonverteringar men inte överväger numeriska konverteringar:
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
Information om C#-konverteringar finns i kapitlet Konverteringar i C#-språkspecifikationen.
Typtestning med mönstermatchning
Operatorn is
testar också ett uttrycksresultat mot ett mönster. I följande exempel visas hur du använder ett deklarationsmönster för att kontrollera körningstypen för ett uttryck:
int i = 23;
object iBoxed = i;
int? jNullable = 7;
if (iBoxed is int a && jNullable is int b)
{
Console.WriteLine(a + b); // output 30
}
Information om de mönster som stöds finns i Mönster.
as-operatorn
Operatorn as
konverterar uttryckligen resultatet av ett uttryck till en viss referens eller nullbar värdetyp. Om konverteringen inte är möjlig returnerar null
operatorn as
. Till skillnad från ett cast-uttryck utlöser operatorn as
aldrig ett undantag.
Formulärets uttryck
E as T
där E
är ett uttryck som returnerar ett värde och T
är namnet på en typ eller en typparameter, ger samma resultat som
E is T ? (T)(E) : (T)null
förutom att E
endast utvärderas en gång.
Operatorn as
tar endast hänsyn till referens-, null-, boxnings- och avboxningskonverteringar. Du kan inte använda operatorn as
för att utföra en användardefinierad konvertering. Om du vill göra det använder du ett cast-uttryck.
I följande exempel visas hur operatorn as
används:
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
}
Kommentar
Som föregående exempel visar måste du jämföra resultatet av as
uttrycket med null
för att kontrollera om konverteringen lyckas. Du kan använda is-operatorn både för att testa om konverteringen lyckas och, om den lyckas, tilldela resultatet till en ny variabel.
Cast-uttryck
Ett cast-uttryck i formuläret (T)E
utför en explicit konvertering av resultatet av uttrycket E
för att skriva T
. Om det inte finns någon explicit konvertering från typen till E
typ T
uppstår ett kompileringsfel. Vid körningen kanske en explicit konvertering inte lyckas och ett cast-uttryck kan utlösa ett undantag.
I följande exempel visas explicita numeriska konverteringar och referenskonverteringar:
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
Information om explicita konverteringar som stöds finns i avsnittet Explicita konverteringar i C#-språkspecifikationen. Information om hur du definierar en anpassad explicit eller implicit typkonvertering finns i Användardefinierade konverteringsoperatorer.
Andra användningar av ()
Du använder också parenteser för att anropa en metod eller anropa ett ombud.
Annan användning av parenteser är att justera ordningen för att utvärdera åtgärder i ett uttryck. Mer information finns i C#-operatorer.
typeof-operator
Operatorn typeof
hämtar instansen System.Type för en typ. Argumentet till operatorn typeof
måste vara namnet på en typ eller en typparameter, som följande exempel visar:
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]
Argumentet får inte vara en typ som kräver metadataanteckningar. Exempel är följande typer:
dynamic
string?
(eller någon nullbar referenstyp)
Dessa typer representeras inte direkt i metadata. Typerna innehåller attribut som beskriver den underliggande typen. I båda fallen kan du använda den underliggande typen. I stället dynamic
för kan du använda object
. I stället string?
för kan du använda string
.
Du kan också använda operatorn typeof
med obundna generiska typer. Namnet på en obunden allmän typ måste innehålla lämpligt antal kommatecken, vilket är ett mindre än antalet typparametrar. I följande exempel visas användningen av operatorn typeof
med en obunden allmän typ:
Console.WriteLine(typeof(Dictionary<,>));
// Output:
// System.Collections.Generic.Dictionary`2[TKey,TValue]
Ett uttryck kan inte vara ett argument för operatorn typeof
. Använd metoden för att hämta instansen System.Type för körningstypen för ett uttrycksresultat Object.GetType .
Typtestning med operatorn typeof
Använd operatorn typeof
för att kontrollera om körningstypen för uttryckets resultat exakt matchar en viss typ. I följande exempel visas skillnaden mellan typkontroll som utförs med operatorn typeof
och is-operatorn:
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
}
}
Överlagring av operator
Operatorerna is
, as
och typeof
kan inte överbelastas.
En användardefinierad typ kan inte överbelasta operatorn ()
, men kan definiera anpassade typkonverteringar som kan utföras av ett cast-uttryck. Mer information finns i Användardefinierade konverteringsoperatorer.
Språkspecifikation för C#
Mer information finns i följande avsnitt i C#-språkspecifikationen: