2009-05-05 4 views

ответ

38

Эрик Липперт сделал все записи в блоге на эту тему.

В целом, основная проблема заключается в том, что это потребовало бы крупной повторной архитектуры C# компилятор, чтобы сделать это. Объявления обрабатываются в один проход. Это потребует нескольких проходов из-за возможности создавать циклы между выведенными переменными. У VB.net есть примерно такая же проблема.

+0

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

+5

Я знаю, что есть способы сделать это. В настоящее время мы не хотим делать ни одного из них; их стоимость не стоит преимуществ. –

+0

Извините, Эрик, я думаю, все, что я пытаюсь сказать, это то, что я рад дождаться рефакторика компилятора, а не голосования за копирование java new(), даже если мы сможем его раньше. Он просто не чувствует, что он подходит, поскольку у нас уже есть var. –

0

Я думаю, что это связано с тем, что объем этого подразумеваемого типа намного шире и, следовательно, более вероятно вызовет проблемы, чем в рамках одного метода.

1

Потому что это намного проще сделать. Если вы хотите сделать вывод о всех типах, нужно будет что-то вроде системы вывода типа Hindley Milner, которая сделает ваш любимый C# на языке производных Haskel.

1

По существу, проблема, с которой вы сталкиваетесь, заключается в том, что C# (пока) является статически типизированным языком. Локальная переменная, определенная как var, все еще статически типизирована, но синтаксически скрыта. С другой стороны, метод, возвращающий var, имеет много последствий. Он становится скорее интерфейсом для использования, и вы ничего не получаете, используя var.

6

У Джареда есть фантастическая ссылка в его ответе, на фантастическую тему.

Я думаю, что он не отвечает на вопрос явно.

Почему бы и нет?

var getFoo() { 
    return new Foo(); 
} 

Причина этого заключается в том:

Что делать, если?

class Foo {} 

var GetFoo() { 
    return GetBar(); 
} 

var GetBar() { 
    return GetBaz(); 
} 

var GetBaz() { 
    return new Foo(); 
} 

Можно сделать вывод, что GetFoo собирается вернуться Foo, но вам придется отслеживать через все вызов, метод делает и его детей делают просто определить тип. В его нынешнем виде компилятор C# не предназначен для работы таким образом. В начале процесса ему нужны методы и типы полей до того, как код, который вводит типы, может работать.

На чисто эстетическом уровне я нахожу определения var на методах путают вещи. Его единственное место, где я думаю, что явное указание всегда помогает, оно защищает вас от стрельбы по себе в ногу, случайно возвращая тип, который заставляет вашу подпись и тонну других зависимых сигнатур методов изменять. Хуже того, вы могли бы изменить все ваши подписи цепочки методов, даже не зная, что вы сделали это, если вы вернете значение метода, возвращающего объект, и ему повезло.

Я думаю, что методы вар лучше оставить для динамических языков, как Ruby,

+11

Нет, это не проблема. Мы уже решили эту проблему на C#, как вы можете продемонстрировать. Если вы сделаете getFoo в лямбда, мы будем выводить возвращаемый тип лямбды как Foo. Существуют реальные проблемы. Одна из проблем заключается в том, что если «var getFoo() {...}» вызывает «var getBar() {...}», который, в свою очередь, вызывает ... вы в конечном итоге должны потенциально провести анализ всей программы только для ввода методы. Текущая архитектура компилятора предполагает, что методы и поля могут быть напечатаны до анализа объектов метода. –

+0

Исправленный и расширенный ответ для отражения –

1

вы можете использовать в VS 2010 Dynamic

Dynamic getFoo() { 
    return new Foo(); 
} 
+0

Если вы буквально не можете писать там тип (например, анонимные типы), это ужасный способ избежать записи длинных имен типов. Вы выбрасываете все (довольно значительные) преимущества статического привязки. –

+0

Но это 'dynamic', в нижнем регистре –

+0

Это так полезно! Это решает все очевидные случаи, когда мне нужно поле, чтобы его тип выводился инициализатором, что для меня много. И Эрик Л. сказал то же самое в начале своей статьи, объясняя, почему нет var для полей. В его статье приводятся объяснения того, как экстремальные рекурсивные случаи являются проблемой, но я не мог понять, почему более распространенный случай не был рассмотрен. К счастью, «динамический» решает это. –

Смежные вопросы