オブジェクト変数のNewは1行でも書けるし2行に分けても書ける
FileSystemObjectクラスやRegExpクラスなどVBAでクラスを利用することがあります。
そのときに、オブジェクト変数(クラスのインスタンス変数)をコードに書くときに2通りの書き方が出来ます。
変数宣言と同時にNewするか、しないか、の違いです。
1 2 |
'// 1行で書く場合 Dim r1 As New RegExp |
1 2 3 |
'// 2行に分けて書く場合 Dim r1 As RegExp Set r1 = New RegExp |
どちらも構文としては正しいコードと判断されます。
変数宣言時にNewするのとSet+Newするのでは何が違うのか
Microsoftはオブジェクト変数の宣言とNewを1行にまとめて書くべきではないと以下のページで書いています。
https://msdn.microsoft.com/ja-jp/library/dd297716.aspx?f=255&MSPPError=-2147217396
Microsoftのヘルプの内容のVBAに関する個所を整理するとこんな感じになります。
条件 | 1行で書いた場合 | 2行で書いた場合 |
---|---|---|
Set obj = Nothing を設定したあとの状態 |
Nothing設定後にオブジェクト変数を参照するとNothingではなくなるため、結果的に、常に「Nothingではない」という状態になる。
その理由は、1行で書いているオブジェクト変数は参照する度にコンストラクタが実行されるため。 |
Nothing設定後にオブジェクト変数を参照してもNothingのままになっている。 |
オーバーヘッドの有無 | オブジェクト変数を参照するたびに「Nothingかどうかのチェック」が実行されるオーバーヘッドがある。 | オーバーヘッドは無い。 |
処理速度 | オーバーヘッドがある分遅い。ただし2行で書いた場合とほとんど変わらない。 | 速い。 |
1行で書こうが2行で書こうがNewと書いてある行でコンストラクタが走らないのはプログラミング言語としてのバグだと思います。
処理速度は計測してみましたがほとんど違いがないことが分かりました。数値上は確かにずれはありますが、誤差の範囲とも言える差でしかありません。
VB6がリリースされた1998年当時のパソコンでは速度の差も目立っていたかもしれませんが、20年後の現在2018年のパソコンであれば気にならないです。
1行で書いてもよいか
上記の通り、1行でNewする方法と2行に分けてNewする方法の2通りの方法で書けるのですが、どちらが正しいのかというと、2行で分ける方が厳密には安全な書き方になります。
Microsoftも2行でよろしくと言ってるのでそれを守った方がいいとは思いますが、ただ、私は1行で書いた場合の欠点に遭遇する確率が極めて低いため、多くの場合でオブジェクト変数の宣言とNewを1行に書きます。
1行で書いた場合の欠点は、Nothingの判定が出来ないことと、コンストラクタが変数宣言時に実行されないこと、処理速度が2行に分けた場合に比べて遅い、という3点ですが、その3点の問題による不具合に遭遇することはまずありません。
そもそもオブジェクト変数とNewを1行で書いている時点で後続処理でNothing判定なんかしませんし、自作クラスでない限りコンストラクタは気にする必要がありませんし、処理速度は変わらない、という感覚でいます。
「コーディングの作法としてNothing判定しないとダメでしょ」という声があるのは分かるのですが、少なくとも私は1行でNewしているFileSystemObjectクラスのオブジェクト変数などがあとの処理でNothingだったため処理できなかった、なんて状況を見たことが一切ありません。そのため、1行でNewを書いておけばNothing判定は必要なくなる、という意識があります。
厳密にしたい方は2行で書いて必要な際にNothing判定でのコーディングをした方が無難でしょうね。私のように「Nothingになることは無い」と割り切っちゃってる人は1行で書いてもいいでしょうね。