Здравствуйте, nt2000, Вы писали:
N>Как определяете при объявлении переменных? Есть признаки или надо просто запомнить?
А можно примеры? Так-то, тут такое разнообразие..
Ну вот ты и ответил на свой вопрос. Константы без new, остальное с new. Список типов констант есть в описании языка, он совсем небольшой. И есть еще одна форма array initializer без new.
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Здравствуйте, nt2000, Вы писали:
N>>
int a=1;
N>>a=2;
N>>a=3;
НС>Ну вот ты и ответил на свой вопрос. Константы без new, остальное с new. Список типов констант есть в описании языка, он совсем небольшой. И есть еще одна форма array initializer без new.
Здравствуйте, nt2000, Вы писали:
N>Как определяете при объявлении переменных? Есть признаки или надо просто запомнить?
Когда имя класса структуры, тогда new.
var a = 1; //Численный литерал, не имя классаvar b = "str"; //строковый литерал, не имя классаvar c = f(a); //выражение, не имя классаvar d = new DateTime(...); // Имя структуры, нужно newvar e = DateTime.Now; // Выражение, не имя классаvar e = new int[10]; // специальный случай для массивов, но целом то же самое, ибо int[] - имя класса массива интов
Здравствуйте, nt2000, Вы писали:
N>Как определяете при объявлении переменных? Есть признаки или надо просто запомнить?
Объявление переменной и new — вещи перпендикулярные. Чтобы объявить переменную, достаточно написать её тип, её имя и всё — переменная объявлена:
int x;
DateTime d;
MyClass instance;
Дальше мы, вероятно, хотим этой переменной что-нибудь присвоить. Вопрос, что именно? Если какое-то уже существующее значение (константу, литерал, результат выражения, значение другой переменной...), то берём и присваиваем без всяких new:
x = 5;
x = y + 10;
dateTime = default;
dateTime = DateTime.Now;
instance = null;
instance = someOtherInstance;
Оператор new требуется, когда нужно создать новый объект ссылочного типа (по-другому новые объекты ссылочных типов не создаются, экзотику не рассматриваю):
MyClass instance1 = new MyClass();
MyClass instance2 = new MyClass(...);
или нужно получить новое значение value-типа, через конструктор этого типа:
DateTime dateTime = new DateTime(...);
Для value-типов альтернативой вызову конструктора может быть ручная инициализация всех имеющихся полей. Например:
struct Vector3
{
public float x, y, z;
public Vector3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
public Vector3(float value)
{
this.x = value;
this.y = value;
this.z = value;
}
}
Можно так:
Vector3 v1 = new Vector3(1, 2, 3); // объявили переменную и вызвали конструктор типа для "конструирования" нового значения этого типа
Vector3 v2 = new Vector3(1); // аналогично
Здравствуйте, alexzzzz, Вы писали:
A>или нужно получить новое значение value-типа, через конструктор этого типа: A>
DateTime dateTime = new DateTime(...);
Интересно чисто для самообразования..
Если переменные ради значений порождают огромные махины — классы, потом после получения желанных значений куда деваются эти классы? болтаются как бедные родственники никому не нужные? а если переменная захочет получить другие значения, то надо рожать опять новый экземпляр?
Здравствуйте, nt2000, Вы писали:
N>Здравствуйте, alexzzzz, Вы писали:
A>>или нужно получить новое значение value-типа, через конструктор этого типа: A>>
DateTime dateTime = new DateTime(...);
N>Интересно чисто для самообразования.. N>Если переменные ради значений порождают огромные махины — классы, потом после получения желанных значений куда деваются эти классы? болтаются как бедные родственники никому не нужные? а если переменная захочет получить другие значения, то надо рожать опять новый экземпляр?
Так, для ясности из какого языка вы на C# перешли?
Здравствуйте, Danchik, Вы писали:
D>Здравствуйте, nt2000, Вы писали:
N>>Здравствуйте, alexzzzz, Вы писали:
A>>>или нужно получить новое значение value-типа, через конструктор этого типа: A>>>
DateTime dateTime = new DateTime(...);
И все-таки, интересно, почему в некоторых языках используется new?
Ведь он усложняет анализ кода.
На память в делфи Class.Create(), в nim — newPerson(), в немерле Class().
C, C#, и, внезапно, F# — new!
т.е. чтобы пользоваться в F# функциональщиной, нужно делать фабричную функцию:
let date () = new DateTime()
let d = date()
Чисто визуально даже, приятней было бы:
let d = DateTime()
В ди например, это имеет особый смысл, там выражение new(uint size,...)
определяет где будет создан объект(по умолчанию в куче), если же new для локальной переменной функции класса, то на стэке.
можно явно указать new(размер выделяемой памяти), естественно, можно расширять поведение инициализации, явно реализуя метод класса вида: new(uint size,int a, string b).
Но в C# по-моему, нужно было разрешить вызывать конструкторы как статические методы. Это логичнее.
В С++ new использует не для создания объекта, а для выделения динамической памяти. А так как сборщиков мусора там нема, то и отдельные ключ слова для выделения/освобождения памяти там очень кстати были.
А во всякие шарпы потащили new — чтоб было похоже на плюсы.
Здравствуйте, varenikAA, Вы писали:
AA>И все-таки, интересно, почему в некоторых языках используется new? AA>Ведь он усложняет анализ кода.
Я считю наоборот, упрощает. Хотя в это дело привычки, если человек начал с питона, то неудобно.
AA>На память в делфи Class.Create(), в nim — newPerson(), в немерле Class(). AA>C, C#, и, внезапно, F# — new!
Чем newPerson лучше new Person?
AA>Но в C# по-моему, нужно было разрешить вызывать конструкторы как статические методы. Это логичнее.
А почему не различать создание объекта здесь и сейчас и делегацию создания -- builder, fabric?
Здравствуйте, nt2000, Вы писали:
A>>или нужно получить новое значение value-типа, через конструктор этого типа: A>>
DateTime dateTime = new DateTime(...);
N>Интересно чисто для самообразования.. N>Если переменные ради значений порождают огромные махины — классы, потом после получения желанных значений куда деваются эти классы? болтаются как бедные родственники никому не нужные? а если переменная захочет получить другие значения, то надо рожать опять новый экземпляр?
Сначала немножко про терминологию.
Есть ссылочные типы: классы, интерфейсы, делегаты, строки, массивы. Переменная ссылочного типа хранит ссылку (грубо говоря, указатель) на объект (по-другому экземпляр) этого типа, расположенный в куче (обычно). А объект/экземпляр в свою очередь хранит в себе полезные и некоторые служебные данные. Т.е. слово класс обозначает какой-то ссылочный тип, а объект или экземпляр класса ― это та штука, в которой хранятся данные этого типа.
Есть value-типы: структуры, перечисления (enum) и все встроенные числовые и логические типы (int, float, bool...). Переменная value-типа хранит непосредственно данные.
Есть ещё отдельно указатели, но хрен с ними.
Согласно спецификации, значением переменной ссылочного типа является ссылка на объект (который где-то там лежит и что-то хранит) или null, значением переменной value-типа являются непосредственно сами данные этого типа.
--
DateTime dateTime = new DateTime(...);
Оператор new нестрашный. В случае value-типов, а DateTime — это структура, value-тип, new просто обозначает вызов конструктора. Никакого объекта где-то в куче не создаётся, просто под переменную выделяется место на стеке (если переменная локальная) и вызывается конструктор, который заполняет это место правильными данными. Если переменная сильно временная и помещается в регистр процессора, то и место в стеке может не выделяться — это на усмотрение jit-компилятора.
никакой разницы не будет. Разве что конкретный JIT-компилятор в конкретных условиях может заинлайнить вызов функции, а может не заинлайнить. Разницы по потреблению памяти точно не будет.
Если тип ссылочный, например строка:
var s = new string('X', 3);
оператор new создаёт в куче экземпляр данного типа и вызывает его конструктор с заданными аргументами, который заполняет экземпляр типа нужными данными. На выходе получаем ссылку на этот экземпляр, которая потом сохраняется в переменную s.
Да, мы создали в куче новый объект, то это никакой не лишний промежуточный объект, а тот самый объект, ссылка на который в итоге будет храниться в переменной s.
Если переменной s позже изменить значение ― присвоить null или ссылку на другой объект, то наш первый объект, если на него больше никто не ссылается, будет сожран сборщиком мусора, если сборщик мусора этого захочет.
Здравствуйте, varenikAA, Вы писали:
AA>Чисто визуально даже, приятней было бы: AA>
AA>let d = DateTime()
AA>
Возможно, я просто привык, но мне нравится, когда вызов конструктора типа визуально отличается от вызова какого-то метода. Не вижу тут каких-то особых неудобств и вопросом, нужно в конкретном месте писать new или не нужно, никогда не задавался.