Почему C# не позволяет объявлять несколько переменных с помощью var?


Учитывая следующее:

// not a problem
int i = 2, j = 3;

Поэтому меня удивляет, что это:

// compiler error: Implicitly-typed local variables cannot have multiple declarators
var i = 2, j = 3;

Не компилируется. Может быть, есть что-то, чего я не понимаю (вот почему я спрашиваю об этом)?

Но почему компилятор не понял, что я имел в виду:

var i = 2;
var j = 3;

Который будет компилироваться.

5 44

5 ответов:

Это просто еще один момент возможной путаницы для программиста и компилятора.

Например, это прекрасно:

double i = 2, j = 3.4;

, но что это значит?

var i = 2, j = 3.4;
С синтаксическим сахаром такие вещи-головная боль, которая никому не нужна,поэтому я сомневаюсь, что ваш случай когда-либо будет поддержан. Это включает в себя слишком много компилятора, пытающегося быть немного слишком умным.

Когда мы разрабатывали функцию, я спросил сообщество, что

var x = 1, y = 1.2;

Должно означать. Вопрос и ответы здесь:

Http://blogs.msdn.com/b/ericlippert/archive/2006/06/26/what-are-the-semantics-of-multiple-implicitly-typed-declarations-part-one.aspx

Http://blogs.msdn.com/b/ericlippert/archive/2006/06/27/what-are-the-semantics-of-multiple-implicitly-typed-declarations-part-two.aspx

Вкратце, около половины респондентов сказали, что очевидно, правильно было бы сделать X и y двойными, и примерно половина респондентов ответили, что очевидно правильно было бы сделать X int и y двойными.

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

Когда половина вашего клиентская база думает, что одна вещь "очевидно правильна", а другая половина считает, что противоположная "очевидно правильна", тогда у вас есть большая проблема с дизайном. Решение состояло в том, чтобы сделать все это незаконным и избежать проблемы.

Потому что если бы это сработало:

var i = 2, j = 3;

Потому что это работает:

var i = 2;
var j = 3;

Тогда вы можете ожидать, что это сработает:

var i = 2, j = "3";

Потому что это работает:

var i = 2;
var j = "3";

Даже в случае, предложенном Джеймсом гонтом, где они оба числовые типы и могут храниться в значении одного и того же типа, каким типом будет i?:

var i = 2, j = 3.4;

j очевидно, что это double, но i логически может быть либо int, либо double, в зависимости от того, как вы ожидали, что var выведет типы. В любом случае если бы он был реализован, вы бы вызвали путаницу у людей, которые ожидали, что он будет работать по-другому.

Чтобы избежать всей этой путаницы, он просто запрещен. Лично я не вижу в этом большой потери; если вы хотите объявить список переменных (что само по себе довольно редко в моем рабочем опыте), просто сильно введите их.

Я думаю, что это слишком ненадежный. Когда две переменные имеют один и тот же тип, это простой частный случай, но в более общем случае вам придется рассмотреть, что является "правильным" в коде, например:

var x = new object(), y = "Hello!", z = 5;

Должны ли они все быть типизированы как object, поскольку это единственный тип, который у них есть общего? Или должен x быть object, y быть string, и z быть int?

С одной стороны, вы можете думать, что первое, так как переменные, объявленные таким образом (все в одной строке), обычно предполагают, что все однотипный. С другой стороны, возможно, вы думаете, что это последнее, так как ключевое слово var обычно должно заставить компилятор выводить наиболее конкретный тип для вас.

Лучше просто запретить это вообще, чем беспокоиться о том, как именно это должно вести себя, учитывая, что это не будет точно "убийственной" функцией в любом случае. По крайней мере, таково мое мнение/догадка.

Я думаю, это потому, что для компилятора это может быть то же самое, что:

var i = 2, j = "three"

И они, конечно же, не одного типа.