Compartilhar via


Melhorias de tipo natural do grupo de métodos

Nota

Este artigo é uma especificação de recurso. A especificação serve como o documento de design para o recurso. Ele inclui alterações de especificação propostas, juntamente com as informações necessárias durante o design e o desenvolvimento do recurso. Esses artigos são publicados até que as alterações de especificação 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 reunião de design de idioma (LDM).

Você pode saber mais sobre o processo de adoção de speclets de recursos no padrão de linguagem C# no artigo sobre as especificações de .

Problema do especialista: 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:

  1. Considere os métodos candidatos escopo a escopo (métodos de instância primeiro e então cada escopo subsequente de métodos de extensão)
  2. Elimine candidatos que não têm nenhuma chance de sucesso, para que não interfiram na determinação de uma assinatura única.
    • Faça a poda dos métodos de instância genérica quando nenhum argumento de tipo é fornecido (var x = M;)
    • Faça a poda de métodos de extensão genéricos baseado na capacidade de reduzir a extensão e nas restrições.

Contexto sobre o tipo natural do grupo de métodos

No C# 10, os grupos de métodos ganharam um tipo natural fraco.
Esse tipo é um "tipo fraco" em que ele só se manifesta quando o grupo de métodos não está tipado como alvo (isto é, não desempenha nenhum papel no 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 terá 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 incluirão o tipo de contenção e todos os escopos do método de extensão.)

Na prática, isso significa que:

  1. Construa o conjunto de todos os métodos candidatos:
  • os métodos no tipo relevante estão no conjunto se eles são estáticos e o receptor é um tipo, ou se eles são não-estáticos e o receptor é um valor
  • métodos de extensão (em todos os escopos) que possam ser reduzidos estão no conjunto
  1. Se as assinaturas de todos os candidatos não corresponderem, o grupo de métodos não terá um tipo natural
  2. 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
  3. Caso contrário, a assinatura resultante será usada como o tipo natural

Proposta

O princípio é analisar escopo por escopo e eliminar o mais cedo possível candidatos que sabemos que não podem ter êxito (mesmo princípio usado na resolução de sobrecarga).

  1. Para cada escopo, criamos o conjunto de todos os métodos candidatos:
  • para o escopo inicial, os métodos no tipo relevante com aridade correspondente aos argumentos de tipo fornecidos e que atendem às restrições com os argumentos de tipo fornecidos estão 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, métodos de extensão nesse escopo que podem ser substituídos pelos argumentos de tipo fornecidos e reduzidos usando o valor do receptor enquanto satisfizerem as restrições estão no conjunto
  1. Se não tivermos candidatos no escopo especificado, prossiga para o próximo escopo.
  2. Se as assinaturas de todos os candidatos não corresponderem, o grupo de métodos não terá um tipo natural
  3. Caso contrário, a assinatura resultante será usada como o tipo natural
  4. Se os escopos estiverem esgotados, o grupo de métodos não terá um tipo natural

Relaciona-se à proposta de escopo por escopo: https://github.com/dotnet/csharplang/issues/7364 Relaciona-se à proposta para gerenciar melhor métodos de extensão genéricos: https://github.com/dotnet/roslyn/issues/69222