Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Tip
Эта статья является частью раздела "Основы" для разработчиков , которые уже знают хотя бы один язык программирования и учат C#. Начните с обзора сопоставления шаблонов , если вы не знакомы с шаблонами. Полные правила совместимости см. в объявлениях и шаблонах типов в справочнике по языку.
Шаблон типа применяется к входным выражениям. C# вычисляет выражение, а затем проверяет, что результирующее значение не равно null и что его тип времени выполнения совместим с указанным типом. Шаблон типа сообщает только о том, успешно ли выполнен тест типа. Он не объявляет переменную.
Задать вопрос, предполагающий ответ «да» или «нет»
В системе доставки IRouteStop — это контракт, определяющий возможности для пунктов назначения, которые принимаются системой планирования маршрутов.
CanRoute проверяет, обладает ли проверяемый пункт назначения такой возможностью, и полученное логическое значение определяет, включается ли пункт назначения в процесс планирования маршрута. Рабочему процессу нужен только ответ «да» или «нет», и он не читает никаких элементов route-stop, поэтому подходит шаблон сопоставления с типом без захватываемой переменной.
static bool CanRoute(object? destination) =>
destination is IRouteStop;
Входное выражение — destination, а IRouteStop — это проверяемый тип. Выберите тип шаблона, если возможны только ответы «да» или «нет». Если в совпадающей ветви нужно получить адрес или обратиться к другому члену через IRouteStop, вместо этого выберите шаблон объявления, чтобы у ветви была переменная этого типа.
Note
Вы также можете увидеть destination is IRouteStop _. Этот синтаксис представляет собой шаблон объявления, в котором _ означает, что никакая переменная не сохраняется. Он выполняет одну и ту же проверку типа, если обе формы допустимы, но destination is IRouteStop более прямо указывает, что это предназначено только для тестирования.
Сопоставление классов и интерфейсов
В системе доставки IRouteStop определяет контракт функциональности для пунктов назначения планирования маршрутов, а RouteStop — это базовый класс, предоставляющий общие данные об остановках маршрута и их реализацию.
ExpressRouteStop — это специализированный класс, производный от RouteStop. В примере проверяется одно вычисляемое значение, чтобы его выходные данные могли продемонстрировать все три совместимых типа. Для каждого теста требуется только логический результат, поэтому не требуется записанная переменная.
interface IRouteStop { }
abstract class RouteStop(string street) : IRouteStop
{
public string Street { get; } = street;
public string GetDisplayName() => Street;
}
sealed class ExpressRouteStop(string street) : RouteStop(street)
{
}
static void ShowCompatibility()
{
object destination = new ExpressRouteStop("8 Oak Avenue");
Console.WriteLine($"Exact class: {destination is ExpressRouteStop}");
Console.WriteLine($"Base class: {destination is RouteStop}");
Console.WriteLine($"Interface: {destination is IRouteStop}");
}
Вычисленное значение — ExpressRouteStop. Выходные данные показывают, что он соответствует точному классу, его RouteStop базовому классу и интерфейсу IRouteStop , который RouteStop реализует.
Подробные правила совместимости и описание особых случаев см. в справочнике по шаблонам типов.
Маршрутизируйте несколько типов
В системе поддержки SupportRequest является базовым классом для специализированных классов запросов, таких как PasswordResetRequest и BillingQuestion.
Ветвь switch связывает шаблон с результатом, который возвращается при совпадении с этим шаблоном. Каждая рука возвращает имя очереди обработки, а последняя рука предоставляет резервную очередь для других вычисляемых значений. Выбранная очередь зависит только от типа времени выполнения вычисляемого значения, поэтому шаблоны типов подходят, так как член запроса не считывается.
static string RouteRequest(object request) =>
request switch
{
PasswordResetRequest => "Identity queue",
BillingQuestion => "Billing queue",
SupportRequest => "General support queue",
_ => "Intake queue"
};
Каждая ветвь определяет тип запроса и возвращает очередь, обрабатывающую этот запрос. Если рука должна считывать элементы запроса, используйте шаблон объявления для записи соответствующего значения в переменной.
Плечи переключателя рассматриваются сверху вниз. Поместите специализированный класс перед базовым классом. В противном случае ветка базового класса может совпадать с любым экземпляром специализированного класса, из-за чего последующая ветка становится недостижимой.
Необязательно. Используйте параметр типа в качестве тестового типа.
Этот необязательный пример основан на универсальных типах и методах.
Параметр типа, такой как TRequest, служит местозаполнителем для типа, который предоставляет вызывающий код. Пакет входящих запросов может содержать несколько типов запросов, а вызывающий предоставляет ConfidentialRequest данные для проверки необходимости конфиденциальной обработки любого запроса. Логический результат выбирает конфиденциальную обработку для всего пакета и создает видимое сообщение о состоянии. Шаблон типа с параметром типа подходит, так как необходимо сохранить только существование соответствующего запроса, поэтому соответствующий объект не должен храниться.
static void ShowConfidentialBatchHandling()
{
object[] incomingRequests = [new BillingQuestion(), new ConfidentialRequest()];
bool requiresConfidentialHandling =
ContainsRequestOfType<ConfidentialRequest>(incomingRequests);
Console.WriteLine(requiresConfidentialHandling
? "Send the entire batch to confidential handling."
: "Send the batch to standard handling.");
}
static bool ContainsRequestOfType<TRequest>(IEnumerable<object> requests)
{
foreach (object request in requests)
{
if (request is TRequest)
{
return true;
}
}
return false;
}
Если вызывающей стороне требуется сам соответствующий запрос, более подходящей была бы операция поиска или фильтрации, возвращающая соответствующие элементы.