Condividi tramite


Miglioramenti ai tipi naturali dei gruppi di metodi

Nota

Questo articolo è una specifica di funzionalità. La specifica funge da documento di progettazione per la funzionalità. Include le modifiche specifiche proposte, insieme alle informazioni necessarie durante la progettazione e lo sviluppo della funzionalità. Questi articoli vengono pubblicati fino a quando le modifiche specifiche proposte non vengono completate e incorporate nella specifica ECMA corrente.

Potrebbero verificarsi alcune discrepanze tra la specifica di funzionalità e l'implementazione completata. Tali differenze vengono acquisite nelle note pertinenti del language design meeting (LDM) .

Altre informazioni sul processo di adozione delle specifiche di funzionalità nello standard del linguaggio C# sono disponibili nell'articolo sulle specifiche di .

Problema del campione: https://github.com/dotnet/csharplang/issues/7429

Sommario

Questa proposta affina la determinazione del tipo naturale di un gruppo di metodi in alcuni modi:

  1. Prendere in considerazione i metodi candidati con ambito per ambito (metodi di istanza, quindi ogni ambito successivo dei metodi di estensione)
  2. Eliminare i candidati che non hanno alcuna possibilità di successo, quindi non interferiscono con la determinazione di una firma univoca:
    • Eliminare i metodi di istanza generica quando non vengono forniti argomenti di tipo (var x = M;)
    • Eliminare i metodi di estensione generici sulla base della possibilità di ridurre l'estensione e i vincoli

Contesto sul tipo naturale del gruppo di metodi

In C# 10 i gruppi di metodi hanno ottenuto un tipo naturale debole.
Tale tipo è un "tipo debole" in quanto entra in gioco solo quando il gruppo di metodi non è tipizzato come destinazione (ad esempio, non svolge alcun ruolo in System.Action a = MethodGroup;).
Questo tipo naturale debole consente scenari come var x = MethodGroup;.

Per riferimento: https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/lambda-improvements.md#natural-function-type

Un gruppo di metodi ha un tipo naturale se tutti i metodi candidati nel gruppo di metodi hanno una firma comune. Se il gruppo di metodi può includere metodi di estensione, i candidati includono il tipo contenitore e tutti gli ambiti del metodo di estensione.

In pratica, ciò significa che:

  1. Costruire il set di tutti i metodi candidati:
  • i metodi sul tipo pertinente si trovano nel set se sono statici e il ricevitore è un tipo o se non sono statici e il ricevitore è un valore
  • i metodi di estensione (in tutti gli ambiti) che possono essere ridotti si trovano nel set
  1. Se le firme di tutti i candidati non corrispondono, il gruppo di metodi non ha un tipo naturale
  2. Se l'arità della firma risultante non corrisponde al numero di argomenti di tipo forniti, il gruppo di metodi non ha un tipo naturale
  3. In caso contrario, la firma risultante viene usata come tipo naturale

Proposta

Il principio è quello di procedere ambito dopo ambito e scartare i candidati che sappiamo non avere successo il prima possibile (lo stesso principio utilizzato nella risoluzione degli overload).

  1. Per ogni ambito, viene creato il set di tutti i metodi candidati:
  • Per l'ambito iniziale, i metodi sul tipo pertinente la cui arità corrisponde agli argomenti di tipo specificati e che soddisfano i vincoli con gli argomenti di tipo forniti sono inclusi nell'insieme se sono statici e il ricevitore è un tipo, o se non sono statici e il ricevitore è un valore.
  • per gli ambiti successivi, i metodi di estensione in tale ambito che possono essere sostituiti con gli argomenti di tipo forniti e ridotti usando il valore del ricevitore e che soddisfano i vincoli, sono inclusi nel set
  1. Se non sono presenti candidati nell'ambito specificato, passare all'ambito successivo.
  2. Se le firme di tutti i candidati non corrispondono, il gruppo di metodi non ha un tipo naturale
  3. In caso contrario, la firma risultante viene usata come tipo naturale
  4. Se gli ambiti vengono esauriti, il gruppo di metodi non ha un tipo naturale

Si riferisce alla proposta di ambito per ambito: https://github.com/dotnet/csharplang/issues/7364 Si riferisce alla proposta per gestire meglio i metodi di estensione generici: https://github.com/dotnet/roslyn/issues/69222