Почему модификаторы ref/out можно указывать только в explicit-anonymous-function-parameter, то есть обязательно совместно с типом?
private delegate bool TryParse<T>(string text, out T result);
// Так можно
TryParse<int> parse1 = (string text, out int result) => Int32.TryParse(text, out result);
// А так нет?
TryParse<int> parse2 = (text, out result) => Int32.TryParse(text, out result);
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Почему модификаторы ref/out можно указывать только в explicit-anonymous-function-parameter, то есть обязательно совместно с типом?
Может потому, что возникает непоределенность с тем, что out может трактоваться на объявление типа?
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, _FRED_, Вы писали:
_FR>>Почему модификаторы ref/out можно указывать только в explicit-anonymous-function-parameter, то есть обязательно совместно с типом?
L>Может потому, что возникает непоределенность с тем, что out может трактоваться на объявление типа?
Тут у них в документации какая-то каша: тут оно в таблице ключевых слов, а тут уже сказано "contextual keyword", хотя если пойти дальше по ссылкам, оно снова называется "keyword".
Как бы там нибыло, в данный момент нельзя использовать имя "out" без "@".
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Почему модификаторы ref/out можно указывать только в explicit-anonymous-function-parameter, то есть обязательно совместно с типом?
_FR>
_FR>private delegate bool TryParse<T>(string text, out T result);
_FR>// Так можно
_FR>TryParse<int> parse1 = (string text, out int result) => Int32.TryParse(text, out result);
_FR>// А так нет?
_FR>TryParse<int> parse2 = (text, out result) => Int32.TryParse(text, out result);
_FR>
_FR>
[имхо]
Типы неявно типизированных параметров выводятся двумя способами — по сигнатуре типа делегата, к которому приводится лямбда-выражение, а в случае нескольких перегрузок (а значит нескольких сигнатур, как в Enumerable.*) — по телу лямбда-выражения. Так вот, в C# невозможно отличить usage ref-параметра от обычного (а вот в F# — можно), поэтому второй способ вывода типов невозможен. То есть в случае таких делегатов C# уже не сможет вывести корректный тип по телу лямбды:
delegate int Foo(int x);
delegate int Bar(ref int x);
x => { ... } // что это?
Мне кажется, что C# team всё же посчитали, что ref/out-модификаторы являются именно частью типа, а так как вывод ref/out-типов иногда вовсе невозможен, то просто запретили ref/out в случае неявно типизированных параметров, а не сделали "не-совсем-неявно-типизированных" параметров, о которых ты говоришь. [/имхо]
Здравствуйте, Пельмешко, Вы писали:
_FR>>Почему модификаторы ref/out можно указывать только в explicit-anonymous-function-parameter, то есть обязательно совместно с типом?
_FR>>private delegate bool TryParse<T>(string text, out T result);
_FR>>// Так можно
_FR>>TryParse<int> parse1 = (string text, out int result) => Int32.TryParse(text, out result);
_FR>>// А так нет?
_FR>>TryParse<int> parse2 = (text, out result) => Int32.TryParse(text, out result);
_FR>>
П>[имхо] П>Типы неявно типизированных параметров выводятся двумя способами — по сигнатуре типа делегата, к которому приводится лямбда-выражение, а в случае нескольких перегрузок (а значит нескольких сигнатур, как в Enumerable.*) — по телу лямбда-выражения. Так вот, в C# невозможно отличить usage ref-параметра от обычного (а вот в F# — можно), поэтому второй способ вывода типов невозможен. То есть в случае таких делегатов C# уже не сможет вывести корректный тип по телу лямбды:
П>delegate int Foo(int x);
П>delegate int Bar(ref int x);
П>x => { ... } // что это?
Можно посмотреть законченный пример использования? Так как не совсем понятно о чём именно речь: неоднозначностей и без модификаторов хватает:
delegate int Foo(int x);
delegate int Boo(int x);
x => { ... } // что это?
П>Мне кажется, что C# team всё же посчитали, что ref/out-модификаторы являются именно частью типа, а так как вывод ref/out-типов иногда вовсе невозможен, то просто запретили ref/out в случае неявно типизированных параметров, а не сделали "не-совсем-неявно-типизированных" параметров, о которых ты говоришь. П>[/имхо]
Частью типа модификаторы и по сути являются, добавляя ссылку Но: вывод и обычных параметров _не всегда_ возможен, однако его сделали, ибо _во многих_ случаях он всё-таки возможен.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Пельмешко, Вы писали:
П>Типы неявно типизированных параметров выводятся двумя способами — по сигнатуре типа делегата, к которому приводится лямбда-выражение,
Это верно.
П>а в случае нескольких перегрузок (а значит нескольких сигнатур, как в Enumerable.*) — по телу лямбда-выражения.
А вот это нет. Если лямбда может быть сконвертирована более чем в один делегат, то возникает неоднозначность и ошибка компиляции.
По коду тела лямбда-выражения выводится только возвращаемый лямбдой тип (при помощи вывода типов return выражений).
П>Так вот, в C# невозможно отличить usage ref-параметра от обычного (а вот в F# — можно), поэтому второй способ вывода типов невозможен.
Вывод возможен, но только по сигнатуре делегата, а не по использованию.
П>Мне кажется, что C# team всё же посчитали, что ref/out-модификаторы являются именно частью типа, а так как вывод ref/out-типов иногда вовсе невозможен, то просто запретили ref/out в случае неявно типизированных параметров, а не сделали "не-совсем-неявно-типизированных" параметров, о которых ты говоришь.
Возможно что C# team решила что пользы от вывода out параметра по сигнатуре делегата нет.
Здравствуйте, Алексей., Вы писали:
П>>а в случае нескольких перегрузок (а значит нескольких сигнатур, как в Enumerable.*) — по телу лямбда-выражения.
А>А вот это нет. Если лямбда может быть сконвертирована более чем в один делегат, то возникает неоднозначность и ошибка компиляции. А>По коду тела лямбда-выражения выводится только возвращаемый лямбдой тип (при помощи вывода типов return выражений).
Здравствуйте, Алексей., Вы писали:
А>Да, здесь неоднозначности не возникает т.к. лямбда может быть сконвертирована только в один из делегатов. А>Говоря о неоднозначности я подразумевал вот такой вариант:
Ну так я лишь показал, что "По коду тела лямбда-выражения выводится только возвращаемый лямбдой тип (при помощи вывода типов return выражений)." неверно. А то, что этот вывод, как и многие другие, в некоторых случаях не срабатывает — вполне очевидные факт.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Ну так я лишь показал, что "По коду тела лямбда-выражения выводится только возвращаемый лямбдой тип (при помощи вывода типов return выражений)." неверно.
Каким образом?
В приведенных примерах осуществляется перебор методов (в алгоритме overload resolution) и как следствие делегатов (т.к. они являются параметрами методов) и попытка привести лямбду у одному из них. Приведение является допустимым только для одного из делегатов. И метод с этим делегатом выбирается. Вывода типов тут нет.
Здравствуйте, Алексей., Вы писали:
_FR>>Ну так я лишь показал, что "По коду тела лямбда-выражения выводится только возвращаемый лямбдой тип (при помощи вывода типов return выражений)." неверно. А>Каким образом?
А>В приведенных примерах осуществляется перебор методов (в алгоритме overload resolution) и как следствие делегатов (т.к. они являются параметрами методов) и попытка привести лямбду у одному из них. Приведение является допустимым только для одного из делегатов. И метод с этим делегатом выбирается. Вывода типов тут нет.
С тем же успехом, если использовать вашу точку зрения, можно утверждать, что и в следующем примере: