Язык программирования C#9 и платформа .NET5
((SalesPerson)emp).SalesNumber);Console.WriteLine();}else if (emp is Manager){Console.WriteLine("{0} had {1} stock options...", emp.Name,((Manager)emp).StockOptions);Console.WriteLine();}}Здесь во время выполнения производится проверка с целью выяснения, на что именно в памяти указывает входная ссылка типа базового класса. После определения, принят ли объект типа
илиSalesPerson, можно применить явное приведение, чтобы получить доступ к специализированным членам данного типа. Также обратите внимание, что помещать операции приведения внутрь конструкцииManagerне обязательно, т.к. внутри разделаtry/catch, выполнившего проверку условия, уже известно, что приведение безопасно.ifНачиная с версии C# 7.0, с помощью ключевого слова
переменной можно также присваивать объект преобразованного типа, если приведение работает. Это позволяет сделать предыдущий метод более ясным, устраняя проблему "двойного приведения". В предшествующем примере первое приведение выполняется, когда производится проверка совпадения типов, и если она проходит успешно, то переменную придется приводить снова. Взгляните на следующее обновление предыдущего метода:isstatic void GivePromotion(Employee emp){Console.WriteLine("{0} was promoted!", emp.Name);// Если SalesPerson, тогда присвоить переменной sif (emp is SalesPerson s){Console.WriteLine("{0} made {1} sale(s)!", s.Name,s.SalesNumber);Console.WriteLine();}// Если Manager, тогда присвоить переменной melse if (emp is Manager m){Console.WriteLine("{0} had {1} stock options...",m.Name, m.StockOptions);Console.WriteLine();}}В версии C# 9.0 появились дополнительные возможности сопоставления с образцом (они были раскрыты в главе 3). Такое обновленное сопоставление с образцом можно использовать с ключевым словом
. Например, для проверки, что объект сотрудника не относится ни к классуis, ни к классуManager, применяйте следующий код:SalesPersonif (emp is not Manager and not SalesPerson){Console.WriteLine("Unable to promote {0}. Wrong employee type", emp.Name);Console.WriteLine();}Использование отбрасывания вместе с ключевым словом is (нововведение в версии 7.0)
Ключевое слово
также разрешено применять в сочетании с заполнителем для отбрасывания переменных. Вот как можно обеспечить перехват объектов всех типов в оператореisилиif:switchif (obj is var _){// Делать что-то}Такое условие будет давать совпадение с чем угодно, а потому следует уделять внимание порядку, в котором используется блок сравнения с отбрасыванием. Ниже показан обновленный метод
:GivePromotion()if (emp is SalesPerson s){Console.WriteLine("{0} made {1} sale(s)!", s.Name, s.SalesNumber);Console.WriteLine();}// Если Manager, тогда присвоить переменной melse if (emp is Manager m){Console.WriteLine("{0} had {1} stock options...", m.Name, m.StockOptions);Console.WriteLine();}else if (emp is var _){// Некорректный тип сотрудникаConsole.WriteLine("Unable to promote {0}. Wrong employee type", emp.Name);Console.WriteLine();}Финальный оператор
будет перехватывать любой экземплярif, не являющийсяEmployee,ManagerилиSalesPerson. Не забывайте, что вы можете приводить вниз к базовому классу, поэтомуPtSalesPersonбудет регистрироваться какPtSalesPerson.SalesPersonЕще раз о сопоставлении с образцом (нововведение в версии 7.0)
В главе 3 было представлено средство сопоставления с образцом C# 7.0 наряду с его обновлениями в версии C# 9.0. Теперь, когда вы обрели прочное понимание приведения, наступило время для более удачного примера. Предыдущий пример можно модернизировать для применения оператора
, сопоставляющего с образцом:switchstatic void GivePromotion(Employee emp){Console.WriteLine("{0} was promoted!", emp.Name);switch (emp)