Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Dica
Este artigo faz parte da seção Conceitos Básicos para desenvolvedores que já conhecem pelo menos uma linguagem de programação e estão aprendendo C#. Comece com a visão geral de correspondência de padrões se os padrões forem novos para você. Para obter as regras completas de compatibilidade, consulte padrões de declaração e de tipo na referência da linguagem.
Um padrão de tipo é aplicado a uma expressão de entrada. O C# avalia a expressão e testa se o valor resultante não é nulo e seu tipo de tempo de execução é compatível com o tipo especificado. Um padrão de tipo relata apenas se o teste de tipo é bem-sucedido. Ele não declara uma variável.
Fazer uma pergunta de tipo sim-or-no
Em um sistema de entrega, IRouteStop é um contrato de capacidade para destinos aceitos pelo planejamento de rotas.
CanRoute testa se o destino avaliado tem essa funcionalidade e seu resultado booliano determina se o destino entra no fluxo de trabalho de planejamento de rotas. O fluxo de trabalho precisa apenas de uma resposta de sim ou não e não lê nenhum membro route-stop, portanto um padrão de tipo sem variável capturada é adequado.
static bool CanRoute(object? destination) =>
destination is IRouteStop;
A expressão de entrada é destinatione IRouteStop é o tipo que está sendo testado. Escolha um padrão de tipo quando a resposta for apenas sim ou não. Se o ramo correspondente precisar ler um endereço ou acessar outro membro por meio de IRouteStop, escolha um padrão de declaração para que o ramo tenha uma variável desse tipo.
Note
Você também pode ver destination is IRouteStop _. Essa sintaxe é um padrão de declaração no qual significa que _ nenhuma variável é retida. Ele executa o mesmo teste de tipo quando ambas as formas são válidas, mas destination is IRouteStop expressa mais diretamente a intenção de apenas testar.
Combinar classes e interfaces
No sistema de entrega, IRouteStop define o contrato de funcionalidade para destinos de planejamento de rotas, enquanto RouteStop é uma classe base que fornece dados comuns de parada de rota e implementação.
ExpressRouteStop é uma classe especializada derivada de RouteStop. O exemplo testa um valor avaliado para que sua saída possa demonstrar todos os três tipos compatíveis. Cada teste precisa apenas de um resultado booliano, portanto, nenhuma variável capturada é necessária.
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}");
}
O valor avaliado é um ExpressRouteStop. A saída mostra que corresponde exatamente à sua classe, à classe base RouteStop e à interface IRouteStop que RouteStop implementa.
Para obter regras detalhadas de compatibilidade e casos extremos, consulte a referência de padrões de tipo.
Rotear vários tipos
Em um sistema de suporte, SupportRequest é a classe base para classes de solicitação especializadas, como PasswordResetRequest e BillingQuestion. Um braço de opção emparelha um padrão com o resultado a ser retornado quando esse padrão corresponder. Cada braço retorna o nome de uma fila de processamento e o braço final fornece uma fila de fallback para outros valores avaliados. A fila selecionada depende apenas do tipo de tempo de execução do valor avaliado, portanto, os padrões de tipo se ajustam porque nenhum membro da solicitação é lido.
static string RouteRequest(object request) =>
request switch
{
PasswordResetRequest => "Identity queue",
BillingQuestion => "Billing queue",
SupportRequest => "General support queue",
_ => "Intake queue"
};
Cada braço responde a uma consulta de tipo e retorna a fila que processa essa solicitação. Se um braço precisar ler os membros da solicitação, use um padrão de declaração para capturar o valor correspondente em uma variável.
Os braços de comutação são considerados de cima para baixo. Coloque uma classe especializada antes de sua classe base. Caso contrário, o braço de classe base pode corresponder a todas as instâncias da classe especializada, o que torna o braço posterior inacessível.
Opcional: usar um parâmetro de tipo como o tipo testado
Este exemplo opcional baseia-se em tipos e métodos genéricos. Um parâmetro de tipo , como TRequest é um espaço reservado para um tipo fornecido pelo chamador. Um lote de solicitação de entrada pode conter vários tipos de solicitação e o chamador fornece ConfidentialRequest para testar se qualquer solicitação requer tratamento confidencial. O resultado booliano seleciona o tratamento confidencial para todo o lote e produz uma mensagem de status visível. Um padrão de tipo com um parâmetro de tipo se encaixa porque apenas a existência de uma solicitação correspondente importa, portanto, o objeto correspondente não precisa ser retido.
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;
}
Se o chamador precisasse da solicitação correspondente em si, uma operação de pesquisa ou filtro que retornasse itens correspondentes seria mais apropriada.