Страницы

Поиск по вопросам

воскресенье, 8 декабря 2019 г.

О юзабельности var при разработке

#c_sharp #linq


Изучая Entity Framework натолкнулся на интересную вещь :

Для создания запроса мы можем использовать var :

var phones = db.Phones.Where(p=> p.Company.Name=="Samsung");

либо явно указывая  тип запроса ,например :

Phone myphone = db.Phones.Where(p=> p.Company.Name=="Samsung");

что меня натолкнуло на интересный вопрос :

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

А теперь наведу несколько примеров ,в которых указаны различия между использованием
var явным указанием типов,почему мне кажется что все-таки var в большинстве случаев
будет юзабельней и читабельней для разработчиков :

1) Для объявления и дальнейшего использования таких структур как списки и словари(к
примеру) которые имеют в себе уже вложенные типы:

Dictionary, String> items = new Dictionary, String>();

Соответственно через var :

var items = new Dictionary, String>();

(Ссылка на вопрос : https://stackoverflow.com/questions/10572693/why-use-var-instead-of-the-class-name)

2) Использование var как итератор при перечислениях в коллекциях :

    class Item {
  public string Name; 
}
foreach ( Item x in col ) {
  Console.WriteLine(x.Name);
}


Код выше - скомпилируется без ошибок ,но при исполнении программы мы получим ошибку
приведения типов . Потому что : сам цикл foreach может работать  с обоими интерфейсами
IEnumerable и IEnumrable . Здесь же результат исполнения имеет тип object и C# компилятор
кастит(приводит) это  к типу Item . Следовательно , это небезопасно и может привести
к ошибке работы программы ,потому что интерфейс IEnumerable может содержать объекты
абсолютно любого типа.

Теперь вариант с var : 

    foreach ( var x in col ) {
  Console.WriteLine(x.Name);
}


Здесь же тип x будет object если интерфейс IEnumerable и T если используется IEnumerable

(Ссылка на вопрос : https://stackoverflow.com/questions/3425966/what-advantages-does-using-var-have-over-the-explicit-type-in-c)

3) И само собой - использование var при запросах + либо получение объекта с уже определенным
типом :

 var l = new List(); // думаю ,очевидно какой тип будет у var
 var s = new SomeClass(); //
 var results = from r in dataContext.SomeTable select r; // Получение выборки из
БД(путем LINQ To Enities)


Или запрос через подход LINQ To Objects : 

var results = from item in someList
          where item != 3
          select item;


UPD: ну и пример с использованием анонимных типов : 

var test = new {Id = 5,Name="Joseph"}

var result = context.MyTable.Select(x=>new {x.Id,x.Name}).ToArray();


(Ссылка на вопрос : https://stackoverflow.com/questions/41479/use-of-var-keyword-in-c-sharp?rq=1)

Краткий вывод из примеров выше  : var - достаточно неплохая вещь ,поскольку он строго
типизирован + правильное название переменных позволяет ещё и повысить читабельность
. Что в суме значительно повышает эффективность кода без ущерба для безопасности 

Вопрос в том : есть ли преимущества использования явного указания типов при объявлении
переменных перед var?

Я просто новатор в этом деле и хотелось бы услышать мнение опытных людей.Спасибо
за конструктивный ответ!
    


Ответы

Ответ 1



var - это ключевое слово для компилятора, а не для человека. Хорошее* использвование var - это когда вы хотите сказать компилятору: Компилятор, тут тип для человека или очевиден из контекста, или вообще неважен. Выведи сам! Плохое* использование var - тип важен для читающего ваш код, неочевиден из контекста, но вы все равно написали var. Тем самым вы говорите разработчику, читающему ваш код через год: Вот ты пытаешься починить в моем коде хитрый баг, набрал себе в голову те 5-7 вещей которые можешь удержать. А теперь выбрось их и начни выяснять тип этой переменной! Стандартное правило: Можно писать var, если при чтении кода человеком тип переменной прямо виден из контекста: тип переменной явно написан в той же строчке: var a = new B() тип переменной неявно написан в той же строчке: var some = BFacrory.Create(); var tasks = dataContext.Tasks; тип прямо следует из кода foreach (var task in dataContext.Tasks) ... и еще куча случаев, которые можно описать как "тип очевиден". Можно писать var, если тип переменной не важен человеку, читающему код. Например, при использовании анонимных типов в цепочке LINQ-запросов. В этом случае важен не конкретный тип, а поля, которые в нем есть - а набор полей прямо виден из контекста. Можно писать var, если ваш код не будет читать никто и никогда. Например, если это временный набросок, который никогда-никогда не станет постоянным. Нельзя писать var во всех остальных случаях. Существует альтернативный подход (с которым я в корне не соглаен), призывающий писать var вообще всегда и везде, кроме случаев, когда компилятор не может вывести тип, либо тип, выведенный компилятором не устраивает разработчика. за такой подход: он очень устойчив к рефакторингу с переименованием и разделением типов против: подобный рефакторинг происходит достаточно редко, отлично поддерживается даже чистой студией, а читабельность кода от принудительно неявного указания типа значительно* страдает. * По мнению автора ответа. Почувствуйте себя человеком, который вынужден перестать читать код ради выяснения, что ж это за var^Wзвездочка.

Ответ 2



Код должен хорошо читаться. Если var способствует этому - используй его. Если нет - не используй. Всё просто. Если из-за обилия var ты не понимаешь в какой момент времени какой тип у тебя хранится в той или иной переменной - не используй var. В противном случае - почему бы и нет? Пример с Dictionary плох тем, что наличие таких generic'ов в проекте - уже само по себе проблема.

Ответ 3



Правило на самом деле очень простое: код должен легко читаться, пониматься и отлаживаться, как вами, так и вашими последователями. Всё, что служит этому — хорошо и правильно, всё, что препятствует этому — плохо и неправильно. Когда у вас стоит выбор между явным именем типа или var (при условии, что нет разницы для программы), подумайте, интересен ли читателю в этой точке точный тип, или нет. Если без указания точного типа текст программы не проиграет в ясности, смело пишите var. Не стоит утомлять читателя ненужными подробностями: знание того, что объект имеет тип List>.Enumerator, обычно не нужно. Но если с var читателю придётся угадывать нужный тип, и этот самый конкретный тип важен, укажите его. В моей практике, чаще всего точный тип неважен: читателю в большинстве случаев всё равно, имеет ли id тип string, int или Id. Но в тех немногих местах, где с id производятся вычисления, точный тип может оказаться важен. Вот в этом-то случае и нужно его указывать явно. Различение случаев, когда точный тип важен и когда неважен, зависит от вашего опыта (и, возможно, от отзывов коллег). Да, а ещё есть случаи, когда язык за вас решает, использовать var или указывать тип. Например, для анонимных типов можно использовать только var (вне контекста обращённых методов, конечно).

Комментариев нет:

Отправить комментарий