|
2016/09/06(Tue) 11:22:24 編集(投稿者)
# 既に回答が付いていますが補足の意味も込めて。
■No81275 (ベア さん) に返信 > 数値を入れることができます。 「数値」に限定しているわけでは無いので、 この場合は「値」ですね。
> 一方で、親アイテムに数値を入れたい場合にはどうしたら良いですか? With の中で With の参照先を入れ替えるのは 基本的に NG であると考えておいてください。
実は「With ステートメント」というものは、 With aaa.bbb.ccc.Button1 .Text = "Withですか?" .BackColor = Color.LightBlue .TextAlign = ContentAlignment.MiddleRight End With というコードを、一時変数を用いた Dim [$W0] = aaa.bbb.ccc.Button1 [$W0].Text = "Withですか?" [$W0].BackColor = Color.LightBlue [$W0].TextAlign = ContentAlignment.MiddleRight という呼び出しにコンパイルするという動作になっています。 (VB では $ で始まる変数名を宣言できないため、あくまで処理イメージですが)
> With aaa.bbb.ccc.Button1 > aaa.bbb.ccc.Button1 = ddd > End With > このようにWithの中であっても省略せずに書くしかないのでしょうか?
いえ、そのような呼び方も本来は NG です。 言語仕様的には問題無いとはいえ、非常に分かりにくいコードになってしまいます。
たとえば With aaa.bbb.ccc.Button1 .Text = "Before" aaa.bbb.ccc.Button1 = ddd .Text = "After" End With のようなコードがあったとしましょう。
この場合、"After" は、一見すると ddd への操作に見えますが、 実際には ddd.Text ではなく、差し替え前の Button1.Text への操作になます。
これは、「.Text = "Before"」や「.Text = "After"」が操作しているのは、 実際には Button1 そのものではなく、With で指定した Button1 への参照を 保持している一時変数「$W0」であるためです。
そのため、With の途中で Button1 の指し示す先を変更したとしても、 $W0 が指しているのは、変更前のインスタンスというわけです。
ちなみにこれは、ByRef 引数な拡張メソッドの呼び出しにも影響します。
================= Imports System.Runtime.InteropServices Imports System.Runtime.CompilerServices Module SampleExtensions '★拡張メソッドの最初の引数を参照渡しにしておく★ <Extension()> Public Sub ChangeInstance(Of T)(<Out()> ByRef this As T, ByVal newInstance As T) this = newInstance '★インスタンスの入れ替え★ End Sub End Module =================
上記の拡張メソッドを用意しておくと、 aaa.bbb.ccc.Button1.ChangeInstance(ddd) のようにして、Button1 の参照先を ddd へと差し替えできます。 差し替え前の Button1 は Nothing であったとしても構いません。
しかしこれを、「With aaa.bbb.ccc.Button1」のブロック内で 『.ChangeInstance(ddd)』と呼び出した場合には、 aaa.bbb.ccc.Button1 が指すインスタンスは ddd にはならないのです。
どうやらこのような呼び出し方だと、ByRef 引数への呼び出しが ByVal 相当の動作で呼び出されるようになっているようなのです。 混乱を防ぐために意図的にそうしているのか、あるいは単に一時変数で あるからなのかは定かではないですが、いずれにせよ、このコードで 参照先の変数が指し変わることはありません。
また、仮に ByRef のまま呼び出されることがあったとしても、先ほどと同様、 変更されるのは aaa.bbb.ccc.Button1 自身ではなく、 一時変数 $W0 だけなので、どちらにせよ意味がないのですけれどね。
なお、上記は ddd や aaa.bbb.ccc.Button1 が「参照型」の場合です。
これらが 値型だった場合、$W0 は「値型」ではなく「値型への参照」となり、 例示した ChangeInstance 拡張メソッドによる入れ替えが働きますし、 With ブロック内で「aaa.bbb.ccc.Button1 = ddd」と差し替えたとしても、 その直後から、ddd への操作に切り替わる事になります。
|