Что использовать: 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
", но большинство примеров будут длиннее этого.