Страницы

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

среда, 17 октября 2018 г.

var или Имя класса или псевдоним?

Добрый день.
Установил себе тут ReSharper. В настройках пока особо не копался, однако что заметил: на все объявления переменных (напрмер Int32 SomeVar или MyClass MyClassEx ) он предлагает переделать на var... С другой стороны Дж Рихтер в CLR via C# советует всегда использовать имена класса, т.е. отказаться даже от использования псевдонимов.
Вот в связи с этим, возник вопрос: Есть ли какие-либо основания (кроме вкусовых предпочтений) использовать в определённых ситуациях определённые способы объявления переменных? ( возможны ли ситуации при которых разные способы объявления переменных по разному будут транслированы в IL?)


Ответ

Да, разница есть: если вы определяете тип переменной явно, он при этом может отличаться от типа выражения в правой части. Для невиртуальных методов это может привести к вызову разного кода.
Пример:
class A { public void Greeting() { Console.WriteLine("Hallo, I am A"); } }
class B : A { public new void Greeting() { Console.WriteLine("Kekeke, I am B"); } }
class Program { static void Main(string[] args) { A a1 = new B(); // заявленный тип переменной a1 - A a1.Greeting(); // выдаёт "Hallo, I am A"
var a2 = new B();// заявленный тип переменной a2 - B a2.Greeting(); // выдаёт "Kekeke, I am B" } }
Тот же эффект с открытыми полями (они всегда невиртуальны) и невиртуальными свойствами.

Существуют случаи, когда вам придётся указывать явный тип (или делать upcast) вручную. Пример:
class C : IDisposable { void IDisposable.Dispose() { } }
Такой код не компилируется:
var c = new C(); c.Dispose(); // нет такого метода
А такой компилируется:
IDisposable c = new C(); c.Dispose();

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

Мне кажется, Рихтер слишком строг. В 2016 году точный тип давно уже не так важен. Семантика, смысл переменных намного важнее. Поэтому я для себя пользуюсь правилом:
Там, где можно (то есть, практически везде), предпочитать алиасы типов (int, а не System.Int32).
Исключение: если это важно и я хочу подчеркнуть, что мой тип содержит именно 32 бита Там, где точный тип переменной реально важен или я хочу сделать на нём акцент, использовать его, иначе использовать var. Например, если какая-то операция возвращает мне Stream или там NetworkStream, мне обычно неважен конкретный тип, и я использую просто var

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

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