Возьмите следующий фрагмент:
List<int> distances = new List<int>();
Была ли избыточность, предусмотренная разработчиками языка? Если да, то почему?
Возьмите следующий фрагмент:
List<int> distances = new List<int>();
Была ли избыточность, предусмотренная разработчиками языка? Если да, то почему?
Причина, по которой код представляется избыточным, заключается в том, что для начинающего программиста он, кажется, определяет одно и то же дважды. Но это не то, что делает код. Он определяет две отдельные вещи, которые просто бывают одного типа. Он определяет следующее:
List<int>
.List<int>
.Рассмотрим следующее:
Person[] coworkers = new Employee[20];
Здесь избыточность более ясна, потому что переменная и выделенный объект имеют два разных типа (ситуация, которая является законной, если тип объектов происходит или реализует тип переменных).
Что такое redudant об этом?
List<int> listOfInts = new List<int>():
Переведено на английский: (EDIT, немного очистили для разъяснения)
Не очень подробный, когда вы думаете о том, что он делает.
Конечно, есть альтернатива:
var listOfInts = new List<int>();
Здесь мы используем вывод типа С#, потому что вы назначаете его немедленно, С# может определить тип, который вы хотите создать, только что созданным в куче.
Чтобы полностью понять, как CLR обрабатывает типы, я рекомендую читать CLR Via С#.
Вы всегда можете сказать:
var distances = new List<int>();
Как говорили другие: var
удаляет избыточность, но имеет потенциальные отрицательные последствия обслуживания. Я бы сказал, что это также имеет потенциальные положительные последствия для обслуживания.
К счастью, Эрик Липперт пишет об этом гораздо более красноречиво, чем я: http://csharpindepth.com/ViewNote.aspx?NoteID=63 http://csharpindepth.com/ViewNote.aspx?NoteID=61
Поскольку объявление типа не обязательно связано с его инициализацией.
Я могу объявить
List<int> foo;
и оставьте его для инициализации позже. Где тогда избыточность? Возможно, он получает значение от другой функции, такой как BuildList().
Как уже упоминалось, новое ключевое слово var позволяет обойти это, но вы должны инициализировать переменную в объявлении, чтобы компилятор мог определить, какой тип он есть.
вместо того, чтобы думать об этом как о избыточном, подумайте об этой конструкции как о функции, которая позволит вам сохранить строку.
вместо
Расстояние до списка; distance = new List();
С# позволяет помещать их в одну строку.
В одной строке говорится: "Я буду использовать переменную, называемую расстоянием, и она будет иметь тип List". В другой строке говорится: "Выделите новый список и вызовите конструктор без параметров".
Это слишком избыточно? Может быть. делать это таким образом дает вам некоторые вещи, хотя
1. Отделяет объявление переменной от размещения объекта. Разрешение:
IEnumerable<int> distances = new List<int>();
// or more likely...
IEnumerable<int> distances = GetList();
2.. Это позволяет более сильную проверку статического типа компилятором, предоставляя ошибки компилятора, когда ваши объявления не соответствуют назначениям, а не ошибкам времени выполнения.
Требуются ли оба из них для написания программного обеспечения? Нет. Существует много языков, которые этого не делают, и/или отличаются во многих других моментах.
"Доктор! Больно, когда я это делаю!" - "Не делай этого больше"
Если вы обнаружите, что вам не нужны или не нужны то, что дает С#, попробуйте другие языки. Даже если вы их не используете, знание других может дать вам огромный импульс в том, как вы приближаетесь к проблемам. Если вы используете один, отлично!
В любом случае вы можете найти достаточную перспективу, чтобы позволить себе сказать: "Мне не нужна строгая проверка статического типа, принудительно выполняемая компилятором С#. Я буду использовать python", а не пылающий С# как слишком избыточный.
Также можно сделать:
var distances = new List<int>();
Улучшения компилятора для С# 3.0 (что соответствует .NET 3.5) устраняют некоторые подобные вещи. Таким образом, ваш код теперь можно записать как:
var distances = new List<int>();
Обновленный компилятор намного лучше разбирает типы на основе дополнительной информации в инструкции. Это означает, что существует меньше случаев, когда вам нужно указать тип либо для назначения, либо как часть общего.
Таким образом, есть еще некоторые области, которые можно было бы улучшить. Некоторые из них являются API, а некоторые из-за ограничений жесткой типизации.
Резервирование не предназначалось, по сути, но было побочным эффектом того факта, что все переменные и поля должны иметь объявление типа. Когда вы принимаете во внимание, что все экземпляры объектов также упоминают имя типа в новом выражении, вы получаете заявления с избыточным выражением.
Теперь с помощью ввода-вывода с использованием ключевого слова var эта избыточность может быть устранена. Компилятор достаточно умен, чтобы понять это. Следующий С++ также имеет ключевое слово auto, которое делает то же самое.
Основная причина, по которой они ввели var, однако, для анонимных типов, которые не имеют имени:
var x = new {Foo = Bar, Number = 1};
Он только "избыточен", если вы сравниваете его с динамически типизированными языками. Он полезен для полиморфизма и поиска ошибок во время компиляции. Кроме того, он упрощает автозавершение кода /intellisense для вашей среды IDE (если вы его используете).
После добавления функциональной поддержки С# определенно становится менее многословным.
Исторический артефакт статического набора текста/Синтаксис; сравните пример Ruby:
distances = []
Используйте var, если очевидно, что тип читателя.
//Use var here
var names = new List<string>();
//but not here
List<string> names = GetNames();
Из microsofts Руководство по программированию на С#
Ключевое слово var также может быть полезно когда конкретный тип переменной является утомительным для ввода на клавиатуре или очевидно, или не добавляет к читаемость кода
Ваш конкретный пример действительно немного подробный, но в большинстве случаев С# довольно скудный.
Я бы предпочел это (С#)
int i;
к этому (VB.NET)
Dim i as Integer
Теперь конкретный пример, который вы выбрали, - это что-то вроде .NET в целом, которое немного на длинной стороне, но я не думаю, что ошибка С#. Может быть, вопрос должен быть перефразирован "Почему .NET-код настолько подробный?"
Я вижу еще одну проблему с использованием var для лени, подобного
var names = new List<string>();
Если вы используете var, переменная с именем "names" вводится как List<string>,
, но в конечном итоге вы будете использовать только один из интерфейсов, унаследованных List<T>.
IList<string> = new List<string>();
ICollection<string> = new List<string>();
IEnumerable<string> = new List<string>();
Вы можете автоматически использовать все это, но можете ли вы рассмотреть, какой интерфейс вы хотели использовать в момент написания кода?
В этом примере ключевое слово var не улучшает читаемость.
Во многих ответах на этот вопрос авторы думают как компиляторы или апологеты. Важным правилом хорошего программирования является Не повторяйте себя!
Избегая этого ненужного повторения, явная цель дизайна Go, например:
Заикание (
foo.Foo* myFoo = new(foo.Foo)
) уменьшается путем простого вывода типа с помощью конструкции:=
declare-and-initialize.
Потому что мы зависим от компиляторов и ошибок компилятора.