Melhorias no tipo natural de grupo de métodos
Observação
Este artigo é uma especificação de recurso. A especificação serve como o documento de design para o recurso. Ele inclui mudanças de especificação propostas, juntamente com as informações necessárias durante o design e desenvolvimento do recurso. Estes artigos são publicados até que as alterações de especificações propostas sejam finalizadas e incorporadas na especificação ECMA atual.
Pode haver algumas discrepâncias entre a especificação do recurso e a implementação concluída. Essas diferenças são capturadas nas notas pertinentes da Language Design Meeting (LDM).
Você pode saber mais sobre o processo de adoção de especificações de recursos no padrão de linguagem C# no artigo sobre as especificações .
Questão campeã: https://github.com/dotnet/csharplang/issues/7429
Resumo
Esta proposta refina a determinação do tipo natural de um grupo de métodos de algumas maneiras:
- Considere métodos candidatos escopo por escopo (métodos de instância primeiro, depois cada escopo subsequente de métodos de extensão)
- Remova candidatos que não têm hipótese de sucesso, para que não interfiram na determinação de uma assinatura exclusiva.
- Prune métodos de instância genérica quando nenhum argumento de tipo é fornecido (
var x = M;
) - Prune métodos de extensão genéricos baseados em ser capaz de reduzir a extensão e em restrições
- Prune métodos de instância genérica quando nenhum argumento de tipo é fornecido (
Contexto sobre o tipo natural do grupo de métodos
Em C# 10, os grupos de métodos ganharam um tipo natural fraco.
Esse tipo é um "tipo fraco" na medida em que só entra em jogo quando o grupo de métodos não é tipado como alvo (ou seja, não desempenha nenhum papel em System.Action a = MethodGroup;
).
Esse tipo natural fraco permite cenários como var x = MethodGroup;
.
Para referência: https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/lambda-improvements.md#natural-function-type
Um grupo de métodos tem um tipo natural se todos os métodos candidatos no grupo de métodos tiverem uma assinatura comum. (Se o grupo de métodos puder incluir métodos de extensão, os candidatos incluem o tipo que contém e todos os escopos do método de extensão.)
Na prática, isto significa que:
- Construa o conjunto de todos os métodos candidatos:
- métodos no tipo relevante estão no conjunto se eles são estáticos e o recetor é um tipo, ou se eles são não-estáticos e o recetor é um valor
- Os métodos de extensão (em todas as esferas) que podem ser reduzidos estão incluídos no conjunto.
- Se as assinaturas de todos os candidatos não corresponderem, então o grupo de métodos não tem um tipo natural
- Se a aridade da assinatura resultante não corresponder ao número de argumentos de tipo fornecidos, o grupo de métodos não terá um tipo natural
- Caso contrário, a assinatura resultante é usada como o tipo natural
Proposta
O princípio é ir escopo a escopo e podar candidatos que sabemos que não podem ter sucesso o mais cedo possível (mesmo princípio usado na resolução de sobrecarga).
- Para cada escopo, construímos o conjunto de todos os métodos candidatos:
- Para o escopo inicial, os métodos no tipo relevante cuja aridade corresponda aos argumentos de tipo fornecidos e que satisfaçam as restrições com os argumentos de tipo fornecidos estão incluídos no conjunto se forem estáticos e o receptor for um tipo, ou se forem não-estáticos e o receptor for um valor.
- Para escopos subsequentes, os métodos de extensão nesse escopo que podem ser substituídos pelos argumentos de tipo fornecidos e reduzidos com o valor do receptor, enquanto satisfazem as restrições, estão no conjunto.
- Se não tivermos candidatos no âmbito dado, avance para o âmbito seguinte.
- Se as assinaturas de todos os candidatos não corresponderem, então o grupo de métodos não tem um tipo natural
- Caso contrário, a assinatura resultante é usada como o tipo natural
- Se os escopos estiverem esgotados, o grupo de métodos não terá um tipo natural
Relaciona-se com a proposta por âmbito: https://github.com/dotnet/csharplang/issues/7364 Refere-se à proposta para melhor lidar com os métodos genéricos de extensão: https://github.com/dotnet/roslyn/issues/69222
C# feature specifications