C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 30 を表示中)
■14600 / )  Re[9]: ユーザーコントロールのメンバへの参照
□投稿者/ まどか (453回)-(2008/02/22(Fri) 17:42:06)
>>それ以降は勝手にそのインスタンスに対してメンバが実行されます。
>  出来ればもう少しどういうことか説明いただきたいのですが。。 

たとえば、
Form2.Show()
Form2.Text = "A"
Form2.Hide()
の場合
最初に型名が現れたときにNewされインスタンスが出来上がります。
それ以降の同じ型名は最初に作成されたインスタンスが利用され、「同じインスタンス」が保証されます。
上記を書き直すと
Dim _Form2 As New Form2
_Form2.Show()
_Form2.Text = "A"
_Form2.Hide()
と同じ挙動ということです。
しかも、_Form2は名前空間が一緒ならどこからでもアクセスできます。(どこに書いたForm2.〜もという意味)

よく、このやり方をしないほうがよいといわれる理由は
いったい「いつ」「だれが」作成したインスタンスかわからなくなり、
可読性や保守性、最悪テストのしにくさや動作保証のしにくさにつながるからです。
またこの挙動の欠点は、Newされるタイミングが、「たまたま実行しようとしたときに初めて出てきたから」であり
動作条件によって変わってしまうからです。
#これは「ここではXXXXプロパティが設定されているはずだ」などの前提を作れないことを意味します。
#前提が作れないということは極端な話、テストできないということ

上記のことを踏まえると、すべて暗黙のフォームインスタンスにしてNewされるタイミングを限定して保証するか
すべて明示的にインスタンスを作成し自分が触っているインスタンスがどこの誰が作ったのかを意識するのどちらかです。

>  私は、最初のMain関数内でスタートアップフォームのインスタンスを生成してそれを
>  Dim frm as New StarUpForm
>  Application.Run(frm) とするだけで良いと思っておりました。
> 
>  Modulの先頭にも次の記述がいるということでしょうか?
> 
>  Public frm as New StartUpForm ※(ユーザーコントロールが貼り付いているフォーム)

「Dim frm」はローカル変数ですからMainの中だけで参照できます。
ModuleはNewしなくてもよいクラスと考えてください。
そして、frmとModuleはお互いに階層になっているわけではなくそれぞれが独立して存在します。
つまり、お互いに相手を知りません。
片方を呼び出す場合は呼び出すほうが呼ばれるほうを知っている必要があります。
通常Moduleは「どこからでも呼び出せるユーティリティ」という用途で使います。

ここで考えて欲しいのは、Moduleは呼ばれるほうですからプロジェクト内でもより抽象的な存在になります。
そのModuleが具体的なある特定フォームの特定ユーザーコントロールへアクセスする役割かどうか、です。

べき論を抜きにした解決例は次のようになります。

#Form1にUserControl1がある場合。
#例外の考慮は書いていません。

・暗黙のフォームインスタンスの場合
Dim s as String = Form1.UserControl1.InputText

・インスタンスを意識した場合

Public Shared Sub Main()
    Sample.Form1Instance = New Form1
    Application.Run(Sample.Form1.Instance)
End Sub

Public Module Sample
    Public Form1Instance As Form1
    Public Fuction GetUserControlData() As String
        Dim data As String = Form1Instance.UserContorl1.InputText
        Return data
    End Function
End Module

・インスタンスを意識した場合 その2

呼び出す側がインスタンスを渡してあげる。

Public Module Sample
    Public Fuction GetUserControlData(ByVal ctl As MyUserCtl) As String
        Dim data As String = ctl.InputText
        Return data
    End Function
End Module

例 Dim s As String = Sample.GetUserControlData(Form1Instance.UserControl1)

返信 編集キー/


管理者用

- Child Tree -