Почему бы var быть плохой вещью? - PullRequest
47 голосов
/ 13 февраля 2009

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

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

Ответы [ 17 ]

63 голосов
/ 13 февраля 2009

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

С другой стороны, если использование 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's not clear what the type of id is

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

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

также не снижается производительность.
33 голосов
/ 13 февраля 2009
var q = GetQValue();

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

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

прекрасно для меня.

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

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

17 голосов
/ 13 февраля 2009

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

Бывают случаи, когда неясно, что вы сломали вещи, изменив его - главным образом, когда инициализированный тип и (исходный) тип переменной не совпадают, потому что:

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

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

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

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

Примеры:

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

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(); }
}

и т.д.

15 голосов
/ 13 февраля 2009

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

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

8 голосов
/ 13 февраля 2009

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

  1. Не снижает безопасность типов
  2. Это на самом деле повысит безопасность типов в вашем коде, предупреждая вас о неявных приведениях. Лучший пример в выражении foreach
  3. Поддерживает принципы СУХОГО в C #. Это специально для случая объявления, зачем называть имя дважды?
  4. В некоторых случаях это необходимо. Пример анонимных типов
  5. Меньше набора текста без потери функциональности.

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

7 голосов
/ 13 февраля 2009

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

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

5 голосов
/ 13 февраля 2009

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

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

5 голосов
/ 13 февраля 2009

var - это последнее «как расставить брекеты» / венгерская нотация / дебаты об использовании верблюда Правильного ответа нет, но есть люди, которые сидят в крайностях.

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

4 голосов
/ 13 февраля 2009

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

3 голосов
/ 13 февраля 2009

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

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

Тем не менее, C # 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 определенно не будет double, а скорее int.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...