Что использовать:Тип имени var или объекта?[дубликат]

StackOverflow https://stackoverflow.com/questions/236878

Вопрос

На этот вопрос уже есть ответ здесь:

это вопрос, которым я всегда задаюсь при программировании:Что использовать, когда пишем код:

var myFiles = Directory.GetFiles(fullPath);

или

string[] myFiles = Directory.GetFiles(fullPath);

вар является новым и представляет собой Неявно типизированные локальные переменные, поэтому мы можем использовать его только локально, и у него есть такие правила, как не может быть нулевым и т. д., но мне интересно, получим ли мы какие-либо преимущества от его «обычного» использования.

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

Что ты думаешь?

Это было полезно?

Решение

Помимо очевидного использования var с LINQ я также использую его для сокращения объявлений переменных для удобства чтения, например:

var d = new Dictionary<string, Dictionary<string, Queue<SomeClass>>>();

В общем, я получаю своего рода утешение (за неимением лучшего слова) от статической типизации, из-за чего мне не хочется от нее отказываться.Мне нравится ощущение, что я знаю, что делаю, когда объявляю переменную.Объявление переменной не просто сообщает что-то компилятору, оно сообщает что-то человеку, читающему ваш код.

Позволь мне привести пример.Предположим, у меня есть метод, который возвращает List<string>.Этот код, безусловно, правильный, и я думаю, что именно так его написали бы 90% разработчиков C#:

List<string> list = MyMethod();

Очевидно, да?На самом деле, вот место, которое вы могли бы так же легко использовать var.

Это правда.Но этот Версия кода не просто объявляет переменную, она сообщает мне, что собирается сделать человек, написавший ее:

IEnumerable<string> list = MyMethod();

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

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

Редактировать:

Я только что перечитал пост Джона Скита, и мне в глаза бросилась цитата Эрика Липперта:

Неявно типизированные локальные переменные — это всего лишь один небольшой способ уменьшить значение «как» и тем самым подчеркнуть «что».

Я думаю, что на самом деле во многих случаях использование неявной типизации оставляет неявным то, что.Это нормально – не зацикливаться на том, что.Например, я случайно напишу запрос LINQ, например:

var rows = from DataRow r in parentRow.GetChildRows(myRelation)
           where r.Field<bool>("Flag")
           orderby r.Field<int>("SortKey")
           select r;

Когда я читаю этот код, одна из вещей, о которых я думаю, когда я его читаю: «rows является IEnumerable<DataRow>." Потому что я знаю, что запросы LINQ возвращают IEnumerable<T>, и я вижу тип выбранного объекта прямо здесь.

Это тот случай, когда что не имеет было сделано явным.Мне оставалось сделать вывод.

Примерно в 90% случаев, когда я использую LINQ, это не имеет ни малейшего значения.Потому что в 90% случаев следующая строка кода такая:

foreach (DataRow r in rows)

Но нетрудно представить код, в котором было бы очень полезно объявить rows как IEnumerable<DataRow> - код, в котором запрашивалось множество объектов разного типа, было невозможно поместить объявление запроса рядом с итерацией, и было бы полезно иметь возможность проверять rows с IntelliSense.И это вопрос «что», а не «как».

Другие советы

Вы получите огромное разнообразие мнений по этому поводу - от «Использовать var везде» до «использовать только VAR с анонимными типами, где вы в основном должны». Мне нравится Взгляд Эрика Липперта на этот счет:

Любой код — это абстракция.Что делает код «на самом деле» манипулирование данными?Нет.Числа?Биты?Нет.Напряжения?Нет.Электроны?Да, но понимание кода на уровне электронов - плохая идея!Искусство кодирования - выяснить, каков правильный уровень абстракции для аудитории.

На языке высокого уровня всегда существует такая напряженность между тем, что делает код (семантически) и тем, как код его выполняет.Программисты по техническому обслуживанию должны понимать как что, так и как, если они будут успешными в внесении изменений.

Весь смысл LINQ заключается в том, что он массово снижает «как» и массово подчеркивает «что».Используя понимание запроса, программист говорит для будущей аудитории: «Я считаю, что вы не должны знать и не знать, как именно вычисляется этот набор результатов, но вы должны очень заботиться о том, какова семантика полученного набора». Они делают код ближе к внедренному бизнес -процессу и дальше от битов и электронов, которые заставляют его уйти.

Неявно напечатанные местные жители - это всего лишь один маленький способ, которым вы можете снимать то, как и, таким образом, подчеркнуть, что.Правильно ли это делать в конкретном случае, это призыв суждения.Поэтому я говорю людям, что если знание этого типа актуально и его выбор имеет решающее значение для дальнейшей работы метода, то не используйте неявную набор.В явном наборе говорится: «Я говорю вам, как это работает по причине, обращать внимание».Неявное печатание говорит: «Не имеет значения, является ли это списком или клиентом [], что важно, так это то, что это коллекция клиентов».

Лично я не иметь тенденцию использовать его, если тип не достаточно очевиден - где я включаю запросы LINQ как «достаточно очевидные».Я бы не сделал этого ради Directory.GetFiles например, поскольку не совсем очевидно, что это возвращает string[] вместо (скажем) FileInfo[] (или что-то совсем другое) — и это имеет большое значение для того, что вы будете делать позже.

Если в правой части оператора присваивания есть вызов конструктора, я с гораздо большей вероятностью выберу var:совершенно очевидно, какой это будет тип.Это особенно удобно со сложными универсальными типами, например. Dictionary<string,List<int>>.

Лично я использую var только в двух местах:

  1. С анонимными типами, т.е.Связанные с LINQ (где в некоторых случаях требуется var)
  2. Когда оператор объявляет и создает определенный тип того же типа.

то есть.это пример пункта 2:

var names = new List<String>();

Отредактировано:Это ответ на вопрос Джона Скита.

Приведенный выше ответ на самом деле был упрощен.В основном я использую вар где тип:

  1. Не нужно знать (правда, мест не так уж и много)
  2. Невозможно узнать (LINQ, анонимные типы)
  3. В противном случае известно или ясно из кода.

В случае фабричного метода все, что вам нужно знать в месте написания кода, это то, что возвращаемый объект является потомком некоторого типа, и что какой-то тип имеет статический фабричный метод, тогда я бы использовал вар.Так:

var connection = DatabaseConnection.CreateFromConnectionString("...");

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

Я попробовал стиль «использовать var везде»...и вот почему я не стал продолжать его использовать.

  1. Ухудшение читабельности в разы
  2. Ограничивает Intellisense после =
  3. Ввод «var» на самом деле был не намного короче, чем ввод «int», «string» и т. д., особенно с intellisense.

С учетом сказанного, я все еще использую его с LINQ.

Выходец из страны функционального программирования, где господствует вывод типов, я использую var для всех местных жителей, где это возможно.

В Visual Studio, если вы когда-нибудь задаетесь вопросом, какой тип локального объекта, все, что вам нужно сделать, это навести на него курсор мыши.

Этот почта есть несколько хороших рекомендаций о том, когда использовать интерфейс типа var или типы объектов.

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

Я думаю, интересно отметить, как это обычно делается в Haskell.Благодаря Изоморфизм Карри-Говарда, (наиболее общий) тип любого выражения в Haskell может быть выведен, и, таким образом, объявления типов практически нигде не требуются, за некоторыми исключениями;например, иногда вы намеренно хотите ограничить тип чем-то более конкретным, чем можно было бы предположить.

Конечно, то, что требуется, и то, что рекомендуется, — это не одно и то же;на практике, по-видимому, соглашение заключается в том, что определения верхнего уровня всегда имеют объявления типов, тогда как в локализованных определениях объявления типов опускаются.Кажется, это обеспечивает хороший баланс между ясностью для читаемости определения в целом и краткостью для читаемости локальных «вспомогательных» или «временных» определений.Если я правильно понимаю, вы не можете использовать var в первую очередь для определений «верхнего уровня» (таких как метод или глобальная функция), так что я думаю, это переводится как «использовать var везде, где только можно» в мире C#.Конечно, набрав "int" такое же количество нажатий клавиш, как "var", но большинство примеров будут длиннее.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top