Страницы

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

четверг, 12 декабря 2019 г.

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

#c_sharp #language_lawyer #resharper


Добрый день.

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

Вот в связи с этим, возник вопрос: Есть ли какие-либо основания (кроме вкусовых предпочтений)
использовать в определённых ситуациях определённые способы объявления переменных? (
возможны ли ситуации при которых разные способы объявления переменных по разному будут
транслированы в IL?)
    


Ответы

Ответ 1



Да, разница есть: если вы определяете тип переменной явно, он при этом может отличаться от типа выражения в правой части. Для невиртуальных методов это может привести к вызову разного кода. Пример: 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.

Ответ 2



Есть ситуации, где использование var необходимо. Например, объявление анонимных типов, особенно при использовании LINQ. Пример: var some = new { Id = 10, Name = "qwerty" }; Тип создаётся автоматически, и его название знает только компилятор, а потому без var тут не обойтись. IL-код будет генерироваться тот же самый как для типов, "прячущихся" под var, так и для явно объявленных. var - это лишь синтаксический сахар. А вообще следование или игнорирование данной рекомендации Resharper'а в общем и целом дело вкуса. Лично я предпочитаю var в очевидных ситуациях, там, где тип однозначно определяется из правой части. Например, при использовании конструкторов: var some = new MyClass(); В данном случае использование var оправдано во избежание дублирования имени класса (в качестве бонуса если вы захотите поменять тип переменной some на какой-то другой, править придётся на один раз меньше, хотя это мелочи). Однако лучше не использовать var, если из правой части выражения нельзя однозначно определить, что это за тип. Например: var some = GetData(); // тип переменной some не очевиден в этом случае лучше явно указывать тип: MyClass some = GetData(); Из моих личных предпочтений: я не указываю var при использовании примитивов. Вместо var val = 0.0; я предпочитаю писать double val = 0.0; Хотя это можно отнести к частным случаям правила об очевидности типа из правой части.

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

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