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

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

var myFiles = Directory.GetFiles(fullPath);

или

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

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

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

что вы думаете?

Ответ 1

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

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

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

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

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. И это что-то, а не как.

Ответ 2

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

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

На языке высокого уровня есть всегда это напряжение между ЧТО код делает (семантически) и КАК код выполняет его. Обслуживание программисты должны понимать как что и как, если они идут чтобы быть успешным вносить изменения.

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

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

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

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

Ответ 3

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

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

т. это пример точки 2:

var names = new List<String>();

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

Этот ответ был фактически упрощен. В основном, я использую var, где тип:

  • Ненужное знать (не так много мест)
  • Невозможно знать (LINQ, анонимные типы)
  • В противном случае, известное или очищенное от кода

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

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

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

Ответ 4

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

  • Деградированная читаемость в разы
  • Пределы Intellisense после =
  • Ввод "var" действительно был не намного короче, чем набирать "int", "string" и т.д., особенно с intellisense.

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

Ответ 8

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

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