Что-то не так с использованием var для объявления коллекций в запросах LINQ?

2

При использовании LINQ, например:

collection.Select (...);

Лучше сказать:

var result = ...

или

IEnumerable<Point3> result = ...

Я спрашиваю его, потому что он всегда IEnumerable, правильно? Лучше ли быть более явным в этом случае?

Теги:

12 ответов

6

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

Например, если вашему запросу сразу же следует цикл по результату, и этот цикл явно введен, var является разумным выбором, так как он экономит время, выписывая его и не запутывает код до точки, где обслуживание намного сложнее, например:

// uses var instead of IEnumerable<Size>
var items = from item in myItems select item.Size;
foreach (Size size in items)
{
   RecalculateLayout(size);
}

Фактически, в показанном примере даже Size может быть заменен на var, и код будет по-прежнему приемлемо поддерживаться, поскольку типизация вызова метода будет достаточной.

Однако, если ожидается, что запрос вернет одно значение и затем будет использоваться в арифметических операциях, вероятно, вы должны использовать явно типизированные результаты, например:

// using var here means you can't properly interpret
// the intention for the following line or where an error
// lies if something changes to say, use double instead of int.
int offset = myItems.First().Offset;
myConvertedValue = originalValue + offset;
  • 3
    Существует распространенное заблуждение, что var не является строго типизированным. однако, когда дело доходит до типов var и IEnumerable <Size> эквивалентны в приведенном выше примере. Разница в том, тестирует ли компилятор, что правая сторона может быть назначена левой стороне (IEnumerable <T>), или если компилятор выводит тип левой стороны с правой стороны. Однако переменная все еще строго типизирована
  • 0
    На самом деле я не говорил, что var не является строго типизированным в смысле скомпилированного кода - просто в смысле «чтение кода как человека».
3

Вы не всегда будете знать, что такое тип IEnumerable, который полностью зависит от содержимого вызова Select. Если вы возвращаете объявленные типы, то использование var необязательно.

Var был создан, потому что много раз при использовании LINQ вы создавали анонимные типы, которые не могут быть объявлены.

3

Ну, это может быть IQueryable вместо IEnumerable.

Когда я пишу код, я обычно использую var по умолчанию, потому что он требует меньше печатать и меньше думать. В какой-то момент перед проверкой (обычно сразу после окончания строки) я изменяю var на точный тип.

С помощью плагина Resharper замена "var" на фактический тип - это однократная комбинация клавиш. Таким образом, я получаю лучшее из обоих миров. Я думаю, что наличие явного типа делает код более легким для просмотра, так что то, что должно быть проверено.

3

Я предпочитаю var. Он короткий и сладкий. Плюс, если вы перейдете с Point3 на Point4 по дороге, это займет меньше места.

1

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

В большинстве случаев вы не заботитесь о типе, это просто не важно. Сам запрос имеет тенденцию удерживать более ценную информацию, а не тип.

1

Сгенерированный IL идентичен, поэтому это проблема стиля/личного предпочтения.

Лично я обычно предпочитаю писать var, так как обычно очень очевидно, что я делаю, когда собираюсь перечислить коллекцию на основе имени переменной коллекции. Тем не менее, бывают случаи, когда явное может сделать код более удобочитаемым, в котором его использование полезно.

0

Мне нравится использовать var при объявлении переменных и создании экземпляра в той же строке, если имя типа немного длинное (или использует generics):

var dictionary = new Dictionary<string, string>();

// instead of:

Dictionary<string, string> dictionary = new Dictionary<string, string>();

Или в цикле foreach, где имя типа переменной item немного длиннее:

foreach (var item in dictionary) { /* do stuff */ }

// instead of:

foreach (KeyValuePair<string, string> item in dictionary) { /* do stuff */ }

Или в серии каскадных using-statements, чтобы хорошо выровнять элементы:

using (var inputStream = CreateInputStream())
using (var inputReader = new StreamReader(inputStream, Encoding.UTF8))
using (var outputStream = CreateOutputStream())
using (var outputWriter = new StreamWriter(outputStream, Encoding.UTF8))
{ /* do stuff */ }

// instead of:

using (Stream inputStream = CreateInputStream())
using (StreamReader inputReader = new StreamReader(inputStream, Encoding.UTF8))
using (Stream outputStream = CreateOutputStream())
using (StreamWriter outputWriter = new StreamWriter(outputStream, Encoding.UTF8))
{ /* do stuff */ }
0

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

Конечно, в быстрых и грязных приложениях я использую его, потому что я ленив:)

0

Недавно мне сказали, что var является лучшей практикой для этого сценария, поскольку он все еще будет строго типизирован. Этот тип определяется во время компиляции и получает сильный тип, назначенный ему компилятором voodoo.

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

0

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

0

Я считаю, что это зависит. Обычно вас не беспокоит то, что вы действительно получаете, если List, IEnumerable, IQueryable или что-то еще.

ИМХО, когда тип, который вы получаете, важен для понимания, лучше писать тип:).

0

var лучше в том смысле, что он сохраняет типизацию и может сделать код более семантически понятным, но было бы неправильно предполагать, что результат всегда IEnumerable. IQueryable также является возможностью, в зависимости от типа коллекции, на которую вы воздействуете, а также в зависимости от выполняемой вами инструкции linq!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню