Представляем краткость в C # / Java - PullRequest
7 голосов
/ 08 апреля 2009

Фон

В настоящее время, если я хочу создать new объект в C # или Java, я набираю что-то похожее на следующее:

List<int> listOfInts = new List<int>(); //C#
ArrayList<String> data = new ArrayList<String>(); //Java

C # 3.0 стремился улучшить краткость, реализуя следующую хитрость компилятора:

var listofInts = new List<int>();

Вопрос

Поскольку компилятор уже знает, что я хочу создать новый объект определенного типа (из-за того, что я создаю его экземпляр, не присваивая ему ссылку null или назначая конкретный метод для его создания), то почему я не могу сделать следующее?

    //default constructors with no parameters:
    List<int> listOfInts = new(); //c#
    ArrayList<String> data = new(); //Java

Последующие вопросы:

  1. Каковы возможные подводные камни этого подхода. Какие крайние случаи я мог пропустить?
  2. Существуют ли другие способы сократить время создания экземпляров (без использования VB6-esque var) и при этом сохранить значение?

ПРИМЕЧАНИЕ. Одним из основных преимуществ, которые я вижу в такой функции, является ясность. Пусть скажем, вар не был ограничен. Для меня это бесполезно, оно собирается получить назначение справа, так зачем беспокоиться? Новый () для меня на самом деле сокращает его и дает смысл. Это новый () то, что вы объявили, что для меня будет ясным и кратким.

Ответы [ 15 ]

0 голосов
/ 22 августа 2011

Я думаю, что Microsoft сделала это следующим образом: а) var xy = new MyClass();

вместо этого способа: б) MyClass xy = new();

потому что а) способен проводить анонимные занятия, а с б) это было бы невозможно.

0 голосов
/ 22 августа 2011

Код читается слева направо (если ваш язык не справа налево).

Это означает, что

var someTypeWithALongName = new TypeWithALongName<TypeParamOne,TypeParamTwo>(); 

помещает важные данные в правую часть (фактический конструктор метода / типа, который используется для инициализации переменной, из которой читатель кода может сделать вывод о фактическом типе переменной ), что менее удобно для глаз, по сравнению с тем, когда он расположен слева.

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

TypeWithALongName<TypeParamOne,TypeParamTwo> someTypeWithALongName = new();

теперь важные данные (фактический тип, который будет иметь переменная) находятся слева, мы можем сканировать код слева и замечать фактические типы, а не забор объявлений var

var x = ....;
var y = ....;
var z = ....;
var xy = ....;

Code Complete В книге говорится, что читаемость является наиболее важной, и мне трудно с этим не согласиться. Экономия 5 (или менее) секунд и использование var вместо реального типа легко усложняет просмотр кода в будущем, может сделать код нечитаемым в зависимости от нужной части и может привести к неожиданным ошибкам, которые будет очень трудно заметить. Все со значением .. экономя 5 секунд и не записывая объявленный тип для переменной?

В настоящее время общеизвестно, что фактическое написание кода не занимает столько времени, сколько затрачивается на создание программы, особенно если это программа product (которая обычно отладка, тестирование системы, интеграция компонентов, проектирование, встречи и т. д. занимают НАМНОГО больше времени, чем фактическое написание кода)

С другой стороны, когда мы печатаем

TypeWithALongName<TypeParamOne,TypeParamTwo> someTypeWithALongName = new();

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

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

TypeWithALongName<TypeParamOne,TypeParamTwo> someTypeWithALongName = new();
AnotherTypeWithLongNname someAnotherTypeWithLongNname = new();
List<int> idList = new();
Dictionary<int,string> lookupDict = new ();

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

Я также считаю, что использование var для объявления переменной и присвоения ее возвращаемому значению какого-либо метода сильно усложняет анализ кода и часто вводит трудно выявляемые ошибки, которых можно было бы полностью избежать, если бы var был невозможен для такие случаи, так что если бы только код конструкторов мог быть сокращен до new() или new(ParamType param), а не какой-то другой метод, такой как

var x = someTypeLocalIstance.ComputeResults()

удобочитаемость выиграет только еще раз.

0 голосов
/ 09 апреля 2009

Java имеет

 List<String> data = newList(); //Java, where newList() is a helper method to create an ArrayList();
 List<String> data = newList("Hello", "World"); // a helper method which takes a T....
 Map<String, List<String>> anagrams = newMap(); // Java, where newMap creates a new  HashMap();
0 голосов
/ 08 апреля 2009

В Java это не имеет особого смысла, так как вы обычно объявляете переменные с типом интерфейса:

List<String> myList = new ArrayList<String>();

Однако в большинстве случаев имеет смысл опустить объявление универсального типа без предупреждений компилятора, например:

List<String> myList = new ArrayList();

Но поскольку Java всегда очень откровенна и многословна во всем, это также может остаться неизменным.

(И с какой стати кто-то еще может написать C # или Java без IDE?)

EDIT:

О, есть предложение для этого! Милая. Спасибо, Брайан.

0 голосов
/ 08 апреля 2009

в C #, уже есть что-то вроде этого, а именно:

var listOfInts = new List<int>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...