Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ponieważ obiekty są polimorficzne, zmienna typu klasy bazowej może przechowywać typ pochodny. Aby uzyskać dostęp do składowych wystąpienia typu pochodnego, należy rzutować wartość z powrotem do typu pochodnego. Jednak rzutowanie tworzy ryzyko rzutowania obiektu InvalidCastException. Język C# udostępnia instrukcje dopasowywania wzorców , które wykonują rzutowanie warunkowo tylko wtedy, gdy powiedzie się. Język C# udostępnia również operatory is i as, które służą do testowania, czy wartość jest określonego typu.
W poniższym przykładzie pokazano, jak zastosować instrukcję is
dopasowywania wzorca.
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 { }
W poprzednim przykładzie pokazano kilka funkcji składni dopasowania wzorca. Instrukcja if (a is Mammal m)
łączy test z przypisaniem inicjalizującym. Przypisanie następuje tylko wtedy, gdy test zakończy się sukcesem. Zmienna m
znajduje się w zakresie tylko w przypadku instrukcji osadzonej if
, do której została przypisana. Nie można uzyskać dostępu m
później w tej samej metodzie. W poprzednim przykładzie pokazano również, jak używać as
operatora do konwertowania obiektu na określony typ.
Można również użyć tej samej składni do testowania, jeśli typ wartości dopuszczanej do wartości null ma wartość, jak pokazano w poniższym przykładzie:
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;
}
}
W poprzednim przykładzie przedstawiono inne funkcje dopasowywania wzorców do użycia z konwersjami. Możesz przetestować zmienną pod kątem wzorca null, sprawdzając bezpośrednio wartość null
. Gdy wartość zmiennej podczas wykonywania jest równa null
, instrukcja sprawdzająca typ is
zawsze zwraca wartość false
. Instrukcja dopasowywania is
wzorca nie zezwala na typ wartości dopuszczający null, taki jak int?
lub Nullable<int>
, ale można przetestować dowolny inny typ wartości. Wzorce is
z poprzedniego przykładu nie są ograniczone do typów wartości dopuszczających wartość null. Można również użyć tych wzorców, aby sprawdzić, czy zmienna typu referencyjnego ma wartość lub jest to null
.
W poprzednim przykładzie pokazano również, jak używać wzorca typu w switch
instrukcji, w której zmienna może być jedną z wielu różnych typów.
Jeśli chcesz sprawdzić, czy zmienna jest danym typem, ale nie przypisując jej do nowej zmiennej, możesz użyć operatorów is
i as
dla typów odwołań oraz typów wartości dopuszczalnych do wartości null. Poniższy kod pokazuje, jak używać instrukcji is
i as
, które były częścią języka C# przed wprowadzeniem dopasowania wzorców, aby sprawdzić, czy zmienna jest określonego typu.
// 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 { }
Jak widać, porównując ten kod z kodem dopasowania wzorca, składnia dopasowania wzorca zapewnia bardziej rozbudowane funkcje, łącząc test i przypisanie w jednej instrukcji. Używaj składni dopasowania wzorca, gdy tylko to możliwe.