Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Étant donné que les objets sont polymorphes, il est possible qu’une variable d’un type de classe de base contienne un type dérivé. Pour accéder aux membres d’instance du type dérivé, il est nécessaire de effectuer un cast pour rétablir la valeur au type dérivé. Toutefois, un cast risque de lever InvalidCastException. C# fournit des instructions relatives aux critères spéciaux, qui effectuent un cast de manière conditionnelle, uniquement en cas de réussite. C# fournit également les opérateurs is et as pour tester si une valeur est d’un certain type.
L’exemple suivant montre comment utiliser l'instruction de correspondance de modèle is
:
var g = new Giraffe();
var a = new Animal();
FeedMammals(g);
FeedMammals(a);
// Output:
// Eating.
// Animal is not a Mammal
SuperNova sn = new SuperNova();
TestForMammals(g);
TestForMammals(sn);
// Output:
// I am an animal.
// SuperNova is not a Mammal
static void FeedMammals(Animal a)
{
if (a is Mammal m)
{
m.Eat();
}
else
{
// variable 'm' is not in scope here, and can't be used.
Console.WriteLine($"{a.GetType().Name} is not a Mammal");
}
}
static void TestForMammals(object o)
{
// You also can use the as operator and test for null
// before referencing the variable.
var m = o as Mammal;
if (m != null)
{
Console.WriteLine(m.ToString());
}
else
{
Console.WriteLine($"{o.GetType().Name} is not a Mammal");
}
}
class Animal
{
public void Eat() { Console.WriteLine("Eating."); }
public override string ToString()
{
return "I am an animal.";
}
}
class Mammal : Animal { }
class Giraffe : Mammal { }
class SuperNova { }
L’exemple précédent illustre quelques fonctionnalités de la syntaxe de correspondance de modèle. L’instruction if (a is Mammal m)
combine le test avec une affectation d’initialisation. L’affectation se produit uniquement lorsque le test réussit. La variable m
se trouve uniquement dans l’étendue de l’instruction if
incorporée, à laquelle elle a été assignée. Vous ne pouvez pas accéder m
ultérieurement dans la même méthode. L’exemple précédent montre également comment utiliser l’opérateuras
pour convertir un objet en un type spécifié.
Vous pouvez également utiliser la même syntaxe pour tester si un type valeur nullable a une valeur, comme illustré dans l’exemple suivant :
int i = 5;
PatternMatchingNullable(i);
int? j = null;
PatternMatchingNullable(j);
double d = 9.78654;
PatternMatchingNullable(d);
PatternMatchingSwitch(i);
PatternMatchingSwitch(j);
PatternMatchingSwitch(d);
static void PatternMatchingNullable(ValueType? val)
{
if (val is int j) // Nullable types are not allowed in patterns
{
Console.WriteLine(j);
}
else if (val is null) // If val is a nullable type with no value, this expression is true
{
Console.WriteLine("val is a nullable type with the null value");
}
else
{
Console.WriteLine("Could not convert " + val.ToString());
}
}
static void PatternMatchingSwitch(ValueType? val)
{
switch (val)
{
case int number:
Console.WriteLine(number);
break;
case long number:
Console.WriteLine(number);
break;
case decimal number:
Console.WriteLine(number);
break;
case float number:
Console.WriteLine(number);
break;
case double number:
Console.WriteLine(number);
break;
case null:
Console.WriteLine("val is a nullable type with the null value");
break;
default:
Console.WriteLine("Could not convert " + val.ToString());
break;
}
}
L’exemple précédent illustre d’autres fonctionnalités de correspondance de modèle à utiliser avec des conversions. Vous pouvez tester une variable pour le modèle Null en vérifiant spécifiquement la null
valeur. Lorsque la valeur d’exécution de la variable est null
, une is
instruction vérifiant un type retourne false
toujours . L'instruction de correspondance de modèle is
n'autorise pas un type valeur nullable, comme int?
ou Nullable<int>
, mais vous pouvez tester n'importe quel autre type valeur. Les is
modèles de l’exemple précédent ne sont pas limités aux types de valeur nullables. Vous pouvez également utiliser ces modèles pour tester si une variable d’un type référence a une valeur ou s’il s’agit null
.
L’exemple précédent montre également comment utiliser le modèle de type dans une instruction où la variable peut être l’un switch
des nombreux types différents.
Si vous souhaitez tester si une variable est d'un type donné, mais sans l'affecter à une nouvelle variable, vous pouvez utiliser les opérateurs is
et as
pour les types de référence et les types de valeur nullables. Le code suivant montre comment utiliser les is
instructions as
qui faisaient partie du langage C# avant que la mise en correspondance des modèles ait été introduite pour tester si une variable est d’un type donné :
// Use the is operator to verify the type.
// before performing a cast.
Giraffe g = new();
UseIsOperator(g);
// Use the as operator and test for null
// before referencing the variable.
UseAsOperator(g);
// Use pattern matching to test for null
// before referencing the variable
UsePatternMatchingIs(g);
// Use the as operator to test
// an incompatible type.
SuperNova sn = new();
UseAsOperator(sn);
// Use the as operator with a value type.
// Note the implicit conversion to int? in
// the method body.
int i = 5;
UseAsWithNullable(i);
double d = 9.78654;
UseAsWithNullable(d);
static void UseIsOperator(Animal a)
{
if (a is Mammal)
{
Mammal m = (Mammal)a;
m.Eat();
}
}
static void UsePatternMatchingIs(Animal a)
{
if (a is Mammal m)
{
m.Eat();
}
}
static void UseAsOperator(object o)
{
Mammal? m = o as Mammal;
if (m is not null)
{
Console.WriteLine(m.ToString());
}
else
{
Console.WriteLine($"{o.GetType().Name} is not a Mammal");
}
}
static void UseAsWithNullable(System.ValueType val)
{
int? j = val as int?;
if (j is not null)
{
Console.WriteLine(j);
}
else
{
Console.WriteLine("Could not convert " + val.ToString());
}
}
class Animal
{
public void Eat() => Console.WriteLine("Eating.");
public override string ToString() => "I am an animal.";
}
class Mammal : Animal { }
class Giraffe : Mammal { }
class SuperNova { }
Comme vous pouvez le voir en comparant ce code au code de correspondance de modèle, la syntaxe de correspondance de modèle fournit des fonctionnalités plus robustes en combinant le test et l’affectation dans une seule instruction. Utilisez la syntaxe de correspondance de modèle dans la mesure du possible.