Поделиться через


Улучшения группы методов естественного типа

Заметка

Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Она включает предлагаемые изменения спецификации, а также информацию, необходимую во время проектирования и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию ECMA.

Может возникнуть некоторое несоответствие между спецификацией компонентов и завершенной реализацией. Эти различия фиксируются в соответствующих заметках собрания по языковому проектированию (LDM).

Дополнительные сведения о процессе внедрения спецификаций функций в стандарт языка C# см. в статье о спецификациях .

Проблема чемпиона: https://github.com/dotnet/csharplang/issues/7429

Сводка

Это предложение определяет естественный тип группы методов несколькими способами:

  1. Рассмотрим методы-кандидаты по области (сначала методы экземпляра, а затем каждая область последующих методов расширения)
  2. Отсейте кандидатов, которые не имеют шансов на успех, чтобы они не мешали определению уникальной подписи.
    • Удалить универсальные методы экземпляра при отсутствии аргументов типа (var x = M;)
    • Обрезать универсальные методы расширения с учетом возможности сокращения и ограничений.

Контекст относительно естественного типа группы методов

В C# 10 группы методов получили слабый естественный тип.
Этот тип является "слабым типом" в том случае, если группа методов не определяется типом-целью (т. е. он не играет никакой роли в System.Action a = MethodGroup;).
Этот слабый естественный тип допускает сценарии, как, например, var x = MethodGroup;.

Для справки: https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/lambda-improvements.md#natural-function-type

Группа методов имеет естественный тип, если все методы кандидатов в группе методов имеют общую сигнатуру. (Если группа методов может включать методы расширения, кандидаты включают содержащий тип и все области методов расширения.)

На практике это означает, что мы:

  1. Сформируйте набор всех методов-кандидатов:
  • Методы соответствующего типа находятся в наборе, если они являются статическими и приемник является типом, или если они являются нестатичными, а приемник является значением.
  • Методы расширения (во всех областях), которые можно уменьшить, находятся в наборе.
  1. Если подписи всех кандидатов не совпадают, группа методов не имеет естественного типа
  2. Если arity результирующей сигнатуры не соответствует количеству предоставленных аргументов типа, то группа методов не имеет естественного типа.
  3. В противном случае результирующая подпись используется в качестве естественного типа.

Предложение

Принцип заключается в том, чтобы рассматривать область за областью и исключать кандидатов, которые, как мы знаем, не смогут достичь успеха как можно раньше (такой же принцип используется в разрешении перегрузки).

  1. Для каждой области мы создадим набор всех методов кандидатов:
  • для начальной области методы соответствующего типа с количеством аргументов, соответствующим предоставленным аргументам типа и удовлетворяющим ограничениям, включаются в набор, если они статические и приемник является типом, или если они нестатические и приемник является значением.
  • для последующих областей методы расширения в этой области, которые могут быть заменены указанными аргументами типа и сокращены с помощью значения приемника при удовлетворении ограничений находятся в наборе.
  1. Если у нас нет кандидатов в данной области, перейдите к следующей области.
  2. Если подписи всех кандидатов не совпадают, группа методов не имеет естественного типа
  3. В противном случае результирующая сигнатура используется в качестве естественного типа
  4. Если области исчерпаны, группа методов не имеет естественного типа

Относится к предложению по областям применения: https://github.com/dotnet/csharplang/issues/7364; относится к предложению о более эффективной обработке универсальных методов расширения: https://github.com/dotnet/roslyn/issues/69222