Почему я должен явно определять все типы с помощью out / ref в лямбда-выражении? - PullRequest
0 голосов
/ 20 февраля 2019

Если у меня есть делегат, определенный с помощью ключевого слова out, например:

delegate int D<TResult, TArgument>(TArgument argument, out TResult result);

И я хочу настроить его с помощью лямбда-выражения, оно должно быть таким:

        D<int, int> d = (int arg, out int rst) =>{...} //correct

Следующие два утверждения неверны :

        D<int, int> d1 = ( arg, out rst) => {...} //CS2046

        D<int, int> d2 = (arg, out int rst) => {...} //CS0748

Итак, мой вопрос: почему C # проектирует так?Я понимаю, что вы должны требовать out, чтобы быть понятным и иметь возможность перегрузки.Но ясно, что rst и arg должны быть int.Почему я должен определить их все? CS0748 говорит мне не делать этого, но не зачем.

На мой взгляд, так и должно быть.Есть ли какие-либо исключения, которые могут вызвать проблему?

D<int, int> d1 = ( arg, out rst) => {...} ////won't compile

Обновление

Похоже, что эта проблема все еще обсуждается в группе разработки C #.Вокруг этого открытого вопроса есть множество предложений в официальном репозитории C # # 338 .

1 Ответ

0 голосов
/ 20 февраля 2019

Похоже, что разработчики языка C # решили, что может быть строго два типа сигнатур анонимных функций - они определены как явная анонимная функция-сигнатура и неявная анонимная-function-signature .

явная-анонимная-функция-подпись является довольно стандартным списком параметров - в скобках (), разделенных запятыми, каждое определение параметра состоит изнеобязательного модификатора (out или ref), типа и идентификатора.

implicit-anonymous-function-signature - это значительно более простой список параметров - между (), заключенные в квадратные скобки и разделенные запятыми, каждое определение параметра состоит только из идентификатора.

Вы не можете смешивать и сопоставлять две формы, вам нужно выбрать одну или другую.Это, вероятно, упрощает синтаксический анализ и делает вывод типов включенным / выключенным, а не «наполовину включенным» (о чем действительно говорит CS0748).

Это, безусловно, позволяет им создавать другие правила внутриязык легче указать, поскольку можно говорить о лямбдах с тем или иным типом подписи.

И поэтому, если вам нужно включить модификатор (out), у вас нет выбора - у вас есть выбориспользовать явную анонимную функцию-подпись .


из спецификации C #, версия 5:

лямбда-выражение :

  • подпись анонимной функции => тело анонимной функции

аноним-Выражение метода :

  • delegate явная анонимная функция-подпись opt block

подпись анонимной функции :

  • подпись явной анонимной функции

  • неявная анонимная функция-подпись

явная анонимная функция-подпись :

  • ( явный анонимный список параметров-функций opt )

явный анонимный список параметров функции :

  • явный параметр анонимной функции

  • явный-анонимный-параметр-список-функций , явный-анонимный-параметр-функция

явный-параметр анонимной функции :

  • модификатор параметра анонимной функции opt тип идентификатор

модификатор параметра-анонимной функции :

  • ref

  • out

неявная анонимная функция-подпись :

  • ( список неявных анонимных функций-параметров опт )

  • неявная анонимная функция-параметр

список неявных анонимных функций-параметров :

  • неявный-параметр анонимной функции

  • список неявных анонимных параметров функции , параметр неявной анонимной функции

параметр неявной анонимной функции :

  • идентификатор
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...