Подтвердить что ты не робот

Почему вар был бы плохим?

Я разговаривал с моими коллегами на днях и слышал, что их стандарт кодирования явно запрещает им использовать ключевое слово var в С#. Они понятия не имели, почему это так, и я всегда находил неявное объявление невероятно полезным при кодировании. У меня никогда не было проблем с определением типа переменной (вы только наводите курсор на переменную в VS, и вы получите такой тип).

Кто-нибудь знает, почему было бы плохой идеей использовать ключевое слово var в С#?

4b9b3361

Ответ 1

Авторы . Руководство по дизайну Net Framework (замечательная книга), появившееся в ноябре 2008 года, рекомендуют рассмотреть возможность использования var, когда тип очевидно и недвусмысленно.

С другой стороны, если использование var приведет к двусмысленности при чтении кода, как указал Антон Гоголев, тогда лучше не использовать его.

в книге (Приложение A), они фактически приводят этот пример:

var names = new List<string>(); // good usage of var

string source = GetSource();
var tokens = source.Split(' '); // ok; most developers know String.Split

var id = GetId(); // Probably not good; it not clear what the type of id is

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

В большинстве случаев использование var для простых типов на самом деле помогает читаемости, и мы не должны забывать, что для использования var также нет штрафа за производительность.

Ответ 2

var q = GetQValue();

действительно плохо. Тем не менее,

var persistenceManager = ServiceLocator.Resolve<IPersistenceManager>();

отлично подходит для меня.

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

Как побочный элемент: Интересно, как они относятся к анонимным типам, если не разрешено использовать ключевое слово var. Или они вообще не используют их?

Ответ 3

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

Есть несколько раз, когда неясно, что вы изменили его, изменив его - в основном, когда тип инициализации и тип (оригинал) не совпадают, потому что:

  • переменная была первоначально базовым классом
  • переменная изначально была интерфейсом
  • переменная была изначально другого типа с неявным оператором преобразования

В этих случаях вы можете столкнуться с проблемами с любым типом разрешения - например:

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

В таких случаях вы меняете смысл кода и выполняете что-то другое. Это плохо.

Примеры:

Неявное преобразование:

static void Main() {
    long x = 17;
    Foo(x);
    var y = 17;
    Foo(y); // boom
}
static void Foo(long value)
{ Console.WriteLine(value); }
static void Foo(int value) {
throw new NotImplementedException(); }

Скрытие метода:

static void Main() {
    Foo x = new Bar();
    x.Go();
    var y = new Bar();
    y.Go(); // boom
}
class Foo {
    public void Go() { Console.WriteLine("Hi"); }
}
class Bar : Foo {
    public new void Go() { throw new NotImplementedException(); }
}

и т.д.

Ответ 4

Конечно, это ошибка. Это потому, что некоторые люди не понимают, что он на самом деле сильно типизирован, а вовсе не как var в VB.

Не все стандарты корпоративного кодирования имеют смысл, я когда-то работал в компании, которая хотела префикс всех имен классов с именем компании. Произошла серьезная переделка, когда компания изменила название.

Ответ 5

Во-первых, как правило, стандарты кодирования должны обсуждаться и согласовываться командой, а аргументы позади них должны быть записаны, чтобы кто-нибудь мог знать, почему они там. Они не должны быть Святой Истиной от одного Учителя.

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

Ответ 6

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

  • Это не снижает безопасность типов.
  • Это фактически увеличит безопасность типа в вашем коде, предупредив вас о неявных переводах. Лучший пример в инструкции foreach
  • Поддерживает DRY-принципы в С#. Это специально для случая с выражением, почему нужно дважды указывать это имя?
  • В некоторых случаях это требуется. Пример анонимных типов
  • Меньше ввод текста без потери функциональности.

http://blogs.msdn.com/jaredpar/archive/2008/09/09/when-to-use-type-inference.aspx

Ответ 7

var - это новейшая "как выложить ваши фигурные скобки" /венгерская нотация/дебаты по теме верблюда. Правильного ответа нет, но есть люди, которые сидят в крайности.

Друг просто несчастен, они работают под одним из экстремистов.

Ответ 8

Запрет на это полностью означает запрет на использование анонимных типов (которые становятся невероятно полезными, поскольку вы используете LINQ больше).

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

Ответ 9

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

Ответ 10

Это действительно проблема чтения с вашим кодом.

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

Однако С# 3.0 с радостью позволит вам использовать var в любом месте, за пределами LINQ и анонимных типов, например:

var myint = 0;
var mystring = "";

абсолютно корректен, а myint и mystring будут строго набираться с помощью выведенных значений, используемых для их инициализации. (таким образом, myint - System.Int32, а mystring - System.String). Конечно, это довольно очевидно при просмотре значений, используемых для инициализации переменных, какие типы они будут неявно напечатаны, однако, я думаю, что это даже лучше для чтения кода, если выше было написано как:

int myint = 0;
string mystring = "";

так как вы сразу можете сразу увидеть, какой тип этих переменных есть.

Рассмотрим этот несколько запутанный сценарий:

var aaa = 0;
double bbb = 0;

Совершенно допустимый код (если немного нетрадиционный), но в приведенном выше, я знаю, что bbb является двойным, несмотря на то, что значение инициализации представляет собой int, но aaa определенно не будет двойным, а скорее int.

Ответ 11

Вы можете считать мнение Microsoft релевантным, поскольку С# - это их язык:

"Однако использование var имеет, по крайней мере, потенциал, чтобы сделать ваш код более понятным для других разработчиков. По этой причине документация на С# обычно использует var strong > только тогда, когда это необходимо.

См. MSDN - неявно типизированные локальные переменные (руководство по программированию на С#), последний абзац.


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

var x = "mistake";     // error not found by compiler
int x = "mistake";     // error found

Поскольку большинство переменных присваивается только один раз, последовательное использование var удаляет почти все тесты типа данных при назначении переменных.

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

Ответ 12

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

Это почти похоже на безопасное для типа, утиное машинописное задание, которое невероятно полезно при рефакторинге. Например, если у меня есть метод, который возвращает List, и я реорганизую его, чтобы возвращать IEnumerable, то любые вызывающие элементы этого метода, которые использовали ключевое слово var и используют только методы IEnumerable, будут в порядке. Если я явно указал, например, List, то мне нужно пойти и изменить его на IEnumerable везде.

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

Ответ 13

Из Департамент отдела резервирования декларации (от Jeff Кодирование ужаса):

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

Я сам думаю, что это стоит заняться, но создание всеобъемлющего руководства о том, когда использовать или нет, будет overkill.

Ответ 14

Эрик Липперт подводит итог > :

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

Мое собственное мнение: мне труднее читать и немного бессмысленно с такими типами, как int, string, bool или даже User. Это о читаемости в конце концов (за исключением тех случаев, когда она используется с LINQ), поэтому, когда vars разбрызгиваются, это может быть труднее прочитать и победить цель ключевого слова, на которое это предназначались разработчики языка.

Ответ 15

У меня были случаи (когда я делал выбор через коллекцию Table.Rows) при использовании var приводил к тому, что тип имел некоторый базовый класс, а не фактический тип DataRow. Это единственный раз, когда у меня были проблемы с var.

Ответ 16

"var" - это четкость

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

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

Джейк поздоровался с Биллом. Он не любил его, поэтому он повернулся и пошел в другую сторону.

Кто пошел другим путем? Джейк или Билл? В этом случае "Джейк" и "Билл" похожи на имя типа. И "Он" и "он" похожи на ключевое слово var. В этом случае это может быть более конкретным. Ниже, например, намного яснее.

Джейк поздоровался с Биллом. Джейк не любил Билла, поэтому он повернулся и пошел в другую сторону.

В этом случае более конкретным было сделано предложение более четким. Но это не всегда будет случай. В некоторых случаях конкретное затрудняет чтение.

Билл любит книги, поэтому Билл пошел в библиотеку, и Билл достал книгу, которую всегда любил Билл.

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

Билл любит книги, поэтому он пошел в библиотеку и достал книгу, которую он всегда любил.

Эти аналогии охватывают суть, но они не рассказывают всю историю. См. В этих примерах был только один способ обратиться к человеку. Либо с их именем, например Биллом, либо более общим путем, как "он" и "он". Но мы работаем только с одним словом.

В случае кода у вас есть два слова, тип и имя переменной.

Person p = GetPerson();

Теперь возникает вопрос, достаточно ли там информации, чтобы вы могли легко определить, что такое p? Знаете ли вы, что люди в этом сценарии:

var p = GetPerson();

Как насчет этого:

var p = Get();

Как насчет этого:

var person = Get();

Или этот:

var t = GetPerson();

Или этот:

var u = Person.Get();

Работает ли ключевое слово var в заданном сценарии, зависит от контекста кода, типа имен переменных, классов и методов, а также сложности кода.

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

Говорят, что иногда я делаю исключения, таковы природа чего-то сложного, а программное обеспечение ничего, если не сложно.

Ответ 17

Вот результаты теста, который я провел по эффективности var по сравнению с явным набором:

  private void btnVar_Click(object sender, EventArgs e)
    {
        Stopwatch obj = new Stopwatch();
        obj.Start();
        var test = "Test";
        test.GetType();
        obj.Stop();
        lblResults.Text = obj.Elapsed.ToString();
    }

    private void btnString_Click(object sender, EventArgs e)
    {
        Stopwatch obj = new Stopwatch();
        obj.Start();
        string test = "Test";
        obj.Stop();
        lblResults.Text = obj.Elapsed.ToString();

    }

Результат первой метки: 00:00:00 000034

Результат второй метки: 00:00:00 00008