Действительно ли объекты нового луга являются устаревшими?

Хорошо, таким образом, вот вопрос... новое устаревшее ключевое слово?

Рассмотрите в C# (и Java, я верю) существуют строгие правила для типов. Классы являются ссылочными типами и могут только быть созданы на "куче". Типы POD создаются на стеке; если Вы хотите выделить их на "куче", необходимо упаковать их в типе объекта. В C#, structs исключение, они могут быть созданы на стеке или "куче".

Учитывая эти правила, это имеет смысл, что мы все еще должны использовать новое ключевое слово? Разве не имело бы смысла для языка использовать надлежащую стратегию выделения на основе типа?

Например, мы в настоящее время должны писать:

SomeClassType x = new SomeClassType();

вместо

SomeClassType x = SomeClassType();

или даже просто

SomeClassType x;

Компилятор, на основе этого, создаваемый тип является ссылочным типом, шел бы вперед и выделил бы память для x на "куче".

Это относится к другим языкам как рубин, php, и др. C/C++ позволяет программисту больше управления, где объекты создаются, таким образом, это имеет серьезное основание потребовать нового ключевого слова.

new просто пережиток с 60-х и нашего C основывал наследие?

8
задан Jeff Paquette 8 January 2010 в 07:25
поделиться

8 ответов

SomeClassType x = SomeClassType();

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

SomeClassType x;

Это не очень полезно, большинство людей объявляют свои переменные так и иногда заполняют их позже, когда это необходимо. Поэтому создавать экземпляр в памяти каждый раз, когда объявляется переменная, нецелесообразно.

18
ответ дан 3 November 2019 в 12:13
поделиться

Если бы вы могли просто написать SomeClassType x; и автоматически инициализировать его, это не позволило бы использовать конструкторы с любыми параметрами. Не каждый SomeClassType будет иметь конструктор без параметров; как компилятор узнает, какие аргументы предоставить?

public class Repository
{
    private IDbConnection connection;

    public Repository(IDbConnection connection)
    {
        if (connection == null)
        {
            throw new ArgumentNullException("connection");
        }
        this.connection = connection;
    }
}

Как бы вы создали экземпляр этого объекта с помощью только Repository rep; ? Для правильной работы требуется зависимый объект.

Не говоря уже о том, что вы можете написать такой код:

Dictionary<int, SomeClass> instances = GetInstancesFromSomewhere();
SomeClass instance;
if (instances.TryGetValue(1, out instance))
{
    // Do something
}

Вы действительно хотите, чтобы он автоматически инициализировался для вас?

Если вы просто написали SomeClassType x = SomeClassType () , тогда это не делает различия между конструктором и методом в области видимости.

В более общем плане :

Я думаю, что существует фундаментальное непонимание того, для чего используется ключевое слово new . Тот факт, что типы значений размещаются в стеке, а «ссылочные» типы размещаются в куче, является деталью реализации . Ключевое слово new является частью спецификации . Как программист, вас не волнует, размещен он в куче или стеке (большую часть времени), но вам нужно указать , как объект инициализируется .

Существуют и другие допустимые типы инициализаторов, такие как:

int[] values = { 1, 2, 3, 4 };

Voilà, инициализация без new . В этом случае компилятор был достаточно умен, чтобы понять это за вас, потому что вы предоставили буквальное выражение, определяющее весь объект.

Итак, я предполагаю, что мой «ответ» - не беспокойтесь о том, где находится объект с точки зрения памяти; используйте ключевое слово new по назначению, как инициализатор объекта для объектов, требующих инициализации.

6
ответ дан 3 November 2019 в 12:13
поделиться

Ваш третий метод не будет работать, поскольку иногда мы хотим определить объект одного типа и присвоить его переменной другого типа. Например:

Stream strm = new NetworkStream();

Мне нужен тип потока (возможно, чтобы куда-то передать), но внутри мне нужен тип NetworkStream.

Также много раз я создаю новый объект при вызове метода:

myobj.Foo(new NetworkStream());

делая это таким образом:

myobj.Foo(NetworkStream()); 

очень сбивает с толку. Я создаю объект или вызываю метод, когда говорю NetworkStream ()?

16
ответ дан 3 November 2019 в 12:13
поделиться

Я занимаюсь программированием на Java в течение нескольких лет, и меня не волнует, находится ли мой объект в куче или стеке. С этой точки зрения мне все равно набирать new или не печатать.

Думаю, это было бы более актуально для других языков.

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

Кстати, я использую (или пытаюсь) использовать ключевое слово new только в заводском методе, поэтому мой клиент все равно выглядит так

SomeClasType x = SomeClasType.newInstance();

См .: Эффективный элемент Java: 1

1
ответ дан 3 November 2019 в 12:13
поделиться

По соображениям производительности это может быть плохой идеей. Например, если вы хотите, чтобы x был ссылкой на уже созданный объект, создание нового объекта и его немедленное удаление было бы пустой тратой памяти и процессорного времени.

3
ответ дан 3 November 2019 в 12:13
поделиться

Разве это не имело бы смысла для язык, чтобы использовать правильное распределение стратегия, основанная на типе?

Именно это уже делает компилятор / среда выполнения C #. Ключевое слово new - это просто синтаксис для создания объекта любым способом, имеющим смысл для этого объекта.

Удаление ключевого слова new сделает менее очевидным вызов конструктора. В качестве аналогичного примера рассмотрим параметры out :

myDictionary.TryGetValue(key, out val);

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

По крайней мере, это оправдание - в современных IDE эти вещи можно было найти и выделить другими способами, помимо фактического вставленного текста.

Новинка, только пережиток 60-х годов. и наше наследие, основанное на C?

Определенно нет. C не имеет ключевого слова новое .

2
ответ дан 3 November 2019 в 12:13
поделиться

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

Если у вас есть несколько конструкторов, это может быть реально уродливым.

0
ответ дан 3 November 2019 в 12:13
поделиться

Для начала:

SomeClassType x;

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

Кроме того, как вы избегаете проблем, где есть метод с тем же именем, что и класс.

Скажи, что вы пишете код:

int World() { return 3; }

int hello = World();

и все приятно и весело.

Теперь вы пишете новый класс позже:

class World 
{
    ...
}

вдруг ваш Int Hello = World () линия неоднозначна.

5
ответ дан 3 November 2019 в 12:13
поделиться