Возьмите следующий фрагмент:
List<int> distances = new List<int>();
Была ли избыточность задумана разработчиками языка? Если да, то почему?
@Rich: Нет, я просто пытаюсь узнать о языковом дизайне. Но как бы то ни было.
@Esteban: Вы назвали это флеймейтом.
Правильный вопрос, конечно, но определенно сформулированный в флеймбейтинговом тоне.
@Rich: Возможно, но очень субъективно. Однако нельзя сказать, что вопрос оффтопный. Это определенно о программировании.
Я отредактирую, чтобы уменьшить флеймбейт.
И там я надеялся, что кто-то будет заинтересован в проектировании систем с резервированием ...





Всегда можно было сказать:
var distances = new List<int>();
Вы могли бы, но не должны! Ключевое слово var разработано для случая, когда разработчик не знает возвращаемый тип, а компилятор знает - как с динамическими типами в linq. Он НЕ предназначен для ленивых программистов.
Использование вывода типа - это не значит быть ленивым.
Или воспользуйтесь выводом типа. Это функция, и вы можете ею воспользоваться. По крайней мере, так обстоит дело во всех языках Другие, поддерживающих вывод типа. Также в linq нет «динамических типов». Он включает в себя функцию, отличную от linq, которая называется «статические анонимные типы, созданные компилятором».
я думаю, он имел в виду анонимные типы. но я прочитал статью ms, в которой говорится, что в этой ситуации нельзя использовать var. я все еще делаю, когда нахожу его более читаемым, как в этой ситуации
Я всегда буду использовать var в этой ситуации! Тип объекта очень ясен из контекста на месте вызова. Однако я бы воздержался от использования var при вызове функции, возвращающей тот же тип, поскольку возвращаемое значение не всегда понятно читателю.
Потому что мы зависимы от компиляторов и ошибок компилятора.
C# определенно становится менее многословным после добавления функциональной поддержки.
Исторический артефакт статической типизации / синтаксиса C; сравните пример Ruby:
distances = []
Немного борется, не так ли? "вар" !? "новый"!? ";" !?
Что такое рубиновый эквивалент создания абстрактного типа из конкретного конструктора?
Руби не заботятся о типах таким образом, Джонатан. Это просто «x = SomeClass.new».
Что в этом лишнего?
List<int> listOfInts = new List<int>():
Переведено на английский: (РЕДАКТИРОВАТЬ, немного подчистил для пояснения)
Не очень многословный, если подумать о том, что он делает.
Конечно, есть альтернатива:
var listOfInts = new List<int>();
Здесь мы используем вывод типа C#, потому что вы назначаете его немедленно, C# может определить, какой тип вы хотите создать, с помощью объекта, только что созданного в куче.
Чтобы полностью понять, как CLR обрабатывает типы, я рекомендую прочитать CLR через C#.
Улучшения компилятора для C# 3.0 (который соответствует .Net 3.5) устраняют некоторые подобные вещи. Итак, ваш код теперь можно записать как:
var distances = new List<int>();
Обновленный компилятор намного лучше определяет типы на основе дополнительной информации в операторе. Это означает, что меньше случаев, когда вам нужно указывать тип либо для назначения, либо как часть Generic.
При этом есть еще некоторые области, которые можно улучшить. Некоторые из них связаны с API, а некоторые просто из-за ограничений строгой типизации.
Вы могли бы, но не должны! Ключевое слово var разработано для случая, когда разработчик не знает возвращаемый тип, а компилятор знает - как с динамическими типами в linq. Он НЕ предназначен для ленивых программистов.
Ваш конкретный пример действительно немного многословен, но в большинстве случаев C# довольно скуден.
Я бы предпочел это (C#)
int i;
к этому (VB.NET)
Dim i as Integer
Выбранный вами конкретный пример касается .NET в целом, что немного длиннее, но я не думаю, что это вина C#. Может быть, вопрос стоит перефразировать: "Почему код .NET такой многословный?"
Потому что объявление типа не обязательно имеет ничего общего с его инициализацией.
Я могу заявить
List<int> foo;
и оставьте его для инициализации позже. Где же тогда избыточность? Возможно, он получает значение от другой функции, например BuildList ().
Как уже упоминалось, новое ключевое слово var позволяет обойти это, но вы имеют инициализируете переменную при объявлении, чтобы компилятор мог определить, какой это тип.
Причина, по которой код кажется избыточным, заключается в том, что начинающему программисту кажется, что он дважды определяет одно и то же. Но это не то, что делает код. Это определение двух разных вещей, которые просто принадлежат к одному и тому же типу. Он определяет следующее:
List<int>.List<int>.Учтите следующее:
Person[] coworkers = new Employee[20];
Здесь отсутствие избыточности более очевидно, поскольку переменная и выделенный объект относятся к двум разным типам (ситуация допустима, если тип объекта является производным от типа переменной или реализует его).
@ Джеффри - красиво сказано. Может потребоваться отредактировать и включить этот Employee, унаследованный от Person, чтобы помочь прояснить ваше объяснение. В противном случае некоторые могут подумать, что Employee [] emp = new Person [] действителен. Что ж, может быть, но кто знает :-)
Я только что заметил, что кто-то проголосовал против этого ответа, и мне любопытно, почему. Мне это кажется простым и точным - я что-то упускаю?
Коллекции - не лучший пример, потому что тот факт, что вы можете делать это с помощью массивов, на самом деле считается недостатком в дизайне языка. Причина в том, что компилятор позволит вам сохранить в коллекции объект, не являющийся сотрудником, производным от человека, но это не удастся во время выполнения.
В примере задающий вопрос использовал коллекцию, а я просто согласился с ней. Я выбрал массив, потому что дженерики не ковариантны и не контравариантны в C# (по крайней мере, пока). Независимо от того, является ли реализация массива в C# ошибочной или нет, она удовлетворяет цели примера.
Да, можно было бы просто использовать List <Person> p = new List <Employee> ();
вместо того, чтобы думать о ней как о лишней, думайте об этой конструкции как о функции, позволяющей вам сохранить строку.
вместо того, чтобы иметь
Перечислить расстояния; расстояния = новый список ();
C# позволяет поместить их в одну строку.
В одной строке написано: «Я буду использовать переменную с именем расстояния, и она будет типа List». В другой строке говорится: «Выделите новый список и вызовите конструктор без параметров».
Это слишком избыточно? Возможно. это даст вам кое-что, хотя
1. Отделяет объявление переменной от размещения объекта. Разрешение:
IEnumerable<int> distances = new List<int>();
// or more likely...
IEnumerable<int> distances = GetList();
2. Он обеспечивает более строгую проверку статического типа компилятором, выдавая ошибки компилятора, когда ваши объявления не соответствуют назначениям, а не ошибки времени выполнения.
Оба ли они необходимы для написания программного обеспечения? Нет. Есть много языков, которые этого не делают и / или различаются по многим другим пунктам.
"Доктор! Мне больно, когда я это делаю!" - "Не делай этого больше"
Если вы обнаружите, что вам не нужны или не нужны вещи, которые дает вам C#, попробуйте другие языки. Даже если вы не используете их, знание других может дать вам огромный толчок в подходе к решению проблем. Если вы его используете - отлично!
В любом случае, вы можете найти достаточно перспективы, чтобы позволить себе сказать: «Мне не нужна строгая статическая проверка типов, обеспечиваемая компилятором C#. Я буду использовать python», вместо того, чтобы считать C# слишком избыточным.
Я подозреваю, что идея плаката заключалась не в том, чтобы требовать спецификации типа для объявлений переменных, а в том, чтобы требовать их, когда информация одинакова. Это справедливая критика, которую разработчики языка приняли во внимание при создании ключевого слова "var".
Избыточность не предназначалась сама по себе, но была побочным эффектом того факта, что все переменные и поля должны были иметь объявление типа. Когда вы принимаете во внимание, что все экземпляры объектов также упоминают имя типа в выражении новый, вы получаете избыточно выглядящие операторы.
Теперь с помощью определения типа с использованием ключевого слова вар эту избыточность можно устранить. Компилятор достаточно умен, чтобы понять это. В следующем C++ также есть ключевое слово авто, которое делает то же самое.
Однако основная причина, по которой они ввели вар, была для анонимных типов, у которых нет имени:
var x = new {Foo = Bar, Number = 1};
Как говорили другие: var удаляет избыточность, но имеет отрицательные последствия обслуживания потенциал. Я бы сказал, что это также имеет потенциальные последствия технического обслуживания положительный.
К счастью, Эрик Липперт пишет об этом более красноречиво, чем я: http://csharpindepth.com/ViewNote.aspx?NoteID=63http://csharpindepth.com/ViewNote.aspx?NoteID=61
Используйте var, если читателю очевидно, что это за тип.
//Use var here
var names = new List<string>();
//but not here
List<string> names = GetNames();
От микрософтс Руководство по программированию на C#
The var keyword can also be useful when the specific type of the variable is tedious to type on the keyboard, or is obvious, or does not add to the readability of the code
Пожалуйста, не делайте этого, поскольку var не предназначен для согласования кода, а для борьбы с динамическими типами linq.
BeowulfOF см. Мое редактирование, это использование var предлагается Microsoft в руководстве по программированию на C#.
Совершенно моя точка зрения. Пожалуйста, будьте внимательны, прежде чем голосовать против людей, не зная более тонких деталей.
Он гласит: «или не добавляет читабельности кода» - так что есть смысл этого не делать.
Если по какой-то причине вы встраиваете несколько общих коллекций, например var lotOfLists = new List <List <List <List <int> >>> ();, это, безусловно, более читабельно, чем альтернатива.
Также может:
var distances = new List<int>();
Вы могли бы, но не должны! Ключевое слово var разработано для случая, когда разработчик не знает возвращаемый тип, а компилятор знает - как с динамическими типами в linq. Он НЕ предназначен для ленивых программистов.
Нет, ты ошибаешься. Если тип очевиден, можно использовать var, как здесь. Вам действительно нужно дважды видеть List <int>?
На самом деле прочтите руководство по программированию msdn C#. Предлагается использовать var для удаления избыточности. А принцип ленивости - это основа программирования. Зачем тратить время, повторяя одно и то же дважды. Это просто стоит денег вашему работодателю.
Почему это помечено как оскорбление?
Я вижу еще одну проблему с использованием 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 не улучшает читаемость в этом примере.
Это только «избыточно», если вы сравниваете его с динамически типизированными языками. Это полезно для полиморфизма и поиска ошибок во время компиляции. Кроме того, это упрощает автоматическое заполнение кода / intellisense для вашей среды IDE (если вы ее используете).
Во многих ответах на этот вопрос авторы мыслят как составители или апологеты. Важное правило хорошего программирования - Не повторяйся!.
Избежать этого ненужного повторения можно с помощью явная цель дизайна Go, например:
Stuttering (
foo.Foo* myFoo = new(foo.Foo)) is reduced by simple type derivation using the:=declare-and-initialize construct.
Это действительно не лучший вопрос.