Этот вопрос затрагивает одну из многих причин, по которой опытным программистам не нравится VB6. Ключевое слово New
изменяет способ работы объявленной переменной. Например:
Dim MyObject As MyClass
Set MyObject = New MyClass
Set MyObject = Nothing
Call MyObject.MyMethod()
... выдает исключение времени выполнения, в то время как это:
Dim MyObject As New MyClass
Set MyObject = Nothing
Call MyObject.MyMethod()
... нет. Лично, если я попытаюсь установить переменную в Nothing
, то ссылка на нее снова - это почти наверняка ошибка, и я бы очень хотел, чтобы программа вылетала, большое спасибо. Это особенно важно в случае, когда класс распределяет ресурсы в инициализаторе (конструкторе) и должен избавиться от ресурсов в деструкторе. Довольно просто написать код, который неправильно ссылается на переменную, установленную на Nothing
, возможно, когда вы хотите проверить значение результата или что-то еще. Это может привести к повторному созданию класса, в результате чего будут удалены все ненужные ресурсы.
Причина этого странного поведения заключается в том, что формы VB6 (которые являются классами) работают так, как их ожидает новичок. Существует неявно объявленная глобальная переменная с тем же именем и типом, что и у каждой определенной формы, поэтому:
Call frmMain.Show
... не падает. Это то же самое поведение. Это действительно делает:
If frmMain Is Nothing Then
Set frmMain = New frmMain
End If
Call frmMain.Show
Это очень сильно противоречит тому, к чему мы привыкли в других объектно-ориентированных языках, поэтому, на мой взгляд, это плохая идея. Он пытается скрыть тот факт, что MyObject
является ссылочным типом, и все же, когда вы пишете что-то вроде этого (без использования Set
):
MyObject = New MyClass
... тогда вы получите исключение runtime вместо ошибки компилятора, потому что вы не использовали команду Set
. Компилятор знает, это ссылочный тип ... почему я должен использовать Set
, и даже если я это сделаю, почему бы не рассказать мне об этом раньше?
В любом случае, чтобы ответить на ваш вопрос, вам редко требуется поведение, подразумеваемое использованием синтаксиса Dim ... New
, поскольку вы хотите контролировать построение и уничтожение объектов. Фактически, единственный раз, когда это имеет смысл, - это создание глобальных одноэлементных объектов (таких как frmMain
выше), где вы просто хотите получить синтаксический сахар. Я бы сказал, что глобальные синглеты - плохая идея, так что если бы я мог отключить возможность использования синтаксиса Dim ... New
, я бы сделал это.