Typtestningsoperatorer och cast-uttryck – is, astypeof 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:

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 nulloperatorn 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 Tuppstå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 dynamicfö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, asoch 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:

Se även