#c_sharp #net
Когда я определяю переменную, одновременно присваивая ей значение, я могу указать класс, наследником которого является результат выражения, могу указать интерфейс, который имплементируется результатом выражени или другой тип, к которому можно неявно привести этот результат. И в этом случае компилятор позволит мне не ошибиться с результатом выражения. Так же я могу не указывать тип переменной, а предоставить эту возможность компилятору, воспользовавшись ключевым словом var. var a = 5; // int var b = 5.0; // double Но когда я определяю константу - компилятор заставляет меня прописать тип константы в явном виде. const int c = 5; const double d = 5.0; С чем связана такая непоследовательность? Неужели тип константы определить сложнее, чем тип переменной?
Ответы
Ответ 1
Eric Lippert, ведущий разработчик компилятора C# отвечал на этот вопрос: https://stackoverflow.com/a/2128581/1159507 Если вкратце то var предназначена для упрощения конструкция типа Dictionary> priceTable = new Dictionary >(); var от слова variable - переменная, В то же время ключевое слово const подчеркивает что что значение меняться не может, поэтому ограничение компилятора тот исключительно логическое, чтоб не было нонсенса типа const var. Ответ 2
Он может. Но, во первых, будет несколько сложнее указать, что нужна именно константа. Как это сделать? var const b = 5.0 Выглядит коряво. Можно, конечно, анализировать, имзеняется ли данная переменная и добавлять константность автоматом: var b1 = 42; // b1 нигде больше ни используется, поэтому b1 - это константа! var b2 = 42; // Где-то в блоке ниже! Ага, b2 - не константа! Это переменная! b2 = 36; Но насколько это хорошо, когда тип переменной и ее поведение зависит от места использования? Другими словами, сделать-то это дело можно, но вот будет ли в этом смысл уверенности нет! К тому же, константы очень легко переносятся из локальных переменных метода в поля, и тут сразу же появляется другая проблема: а не добавить ли неявную типизацию в поля? А это открывает еще пару ящиков Пандорры с котами Шредингера (туц, если интересно). UPDATE: Почему компилятор C# не может вывести тип лямбда-выраженя? (выношу ответ из комментария). Компилятор C# не может вывести тип лямбды: var foo = () => 42; Не из-за ограничений параметрическим полиморфизмом:) Лямбды могут быть преобразованы к Funcили к Expression > и компилятор C# не знает, какой тип треубется пользователю. Вот пример успешного вывода типов: var foo = (Func )(() => 42); UPDATE 2: Почему плохо const b = 5.0? В комментариях был задан вопрос, а почему бы не использовать const b = 5.0? Ничего плохого в этом нет, но можно представить ответ команды разработчиков C# на предложение добавить эту возможность. Вывод типов для константных выражений будет однобоким, если он будет работать в методах, но не будет работать в полях. Это значит, что новая возможность должна быть валидна как минимум в следующих случаях: class Foo { const boo = -42; public Foo() { const foo = 42; } } Вполне логично. Но в этом случае, мы получаем еще одну непоследовательность: вывод типов для констант работает в любом контексте, а вывод типов для переменных - только в рамках метода. Контр аргрументом может служить то, что семантически var не имеет смысла в рамках полей, а значит никакой рассогласованности нет. Но, с другой стороны, появится много желающих получить полноценный вывод типов для полей. Нет никаких проблем добавить вывод типов и для полей (некоторые размышления от Липперта тут), но, получается что маленькая возможность "добавить вывод типов для констант" разрастается в достаточно большую фичу, которая затрагивает слишком много других областей. С другой стороны, сейчас легко можно залить свое предложение на гитхаб и посмотреть, как сами разработчики компилятора на него отреагируют.
Комментариев нет:
Отправить комментарий