2013-08-08T22:57:09の更新内容

programming/vb.net/me_myclass_mybase/index.wiki.txt

current previous
1,478 1,210
~
${smdncms:title,Me, MyClass, MyBase}
${smdncms:title,Me, MyClass, MyBase 〜 MeとMyClassの違い}
~
${smdncms:keywords,Me,MyClass,MyBase,違い,My}
${smdncms:keywords,Me,MyClass,MyBase}
 
${smdncms:meta,toc-amazonlivelink-keyword,books-jp,visual basic}
${smdncms:meta,toc-amazonlivelink-keyword,books-jp,visual basic}
-
C++、VBや、VB.NET、C#にはクラスのインスタンスが自分自身とそのメンバを参照するためのキーワードがあります。 例えばC++ではthisポインタ、VBではMeキーワードなどです。 同様にC#ではthis及びbaseキーワード、VB.NETでは VBから引き続きMeが使われ、新たにMyClassとMyBaseというキーワードが採用されました。 VB.NETとC#でMyBase / baseというキーワードが採用された背景には、共通言語仕様ではクラスの多重継承が認められていないために基底クラスは常に一つであるため、C++のように任意の基底クラスを参照するためにキャストを行う必要がなくなったからと考えられます。
 

        

        
~
[[Me>#MeMyClassKeyword]]はクラスや構造体のインスタンス自身を参照するためのキーワードです。 MyClassもインスタンス自身のメンバを参照する点はMeと同じですが、呼び出そうとするメソッドがオーバーライドされていてもMyClassが使われたクラスの実装が呼び出されるという点がMeとは異なります。 MyClassは自クラスのメンバを参照する場合に使用するのに対して、[[MyBase>#MyBaseKeyword]]は基底クラスのメンバを参照する際に使用します。
このようにVB.NETとC#の MyClass / this と MyBase / base はその機能や目的は同じであるといえます。 ですが、VB.NETにはMyClassに似た働きを持つMeキーワードが存在します。
 

        

        
~
この他にもMe・MyClass・MyBaseとは役割は異なるものの似た名前を持つものとして[[My名前空間>#MyNamespace]]というものも存在します。
#googleadunit
-

          
-
*Me, MyClass, MyBase
-
Meと MyClassの機能の違いに言及する前に、Me・MyClass・MyBaseを使用した例によってその動作を見てみることにします。
-

          
-
#code(vb){{
-
Imports System
 

        

        
~
-関連するページ
' 基底クラス
~
--[[programming/vb.net/basics/12_class]]
Public Class BaseClass
+
--[[programming/vb.net/basics/09_structure]]
+
--[[programming/vb.net/basics/11_accessibility]]
 

        

        
~
#googleadunit
    ' 基底クラスでのMethod()
-
    Protected Overridable Sub Method(ByVal keyword As String)
 

        

        
~
*MeとMyClass [#MeMyClassKeyword]
        Console.WriteLine("Method of BaseClass called by " + keyword)
+
MeとMyClassはよく似た機能を持つキーワードです。 ともにクラスまたは構造体のインスタンス自身のメンバを参照するキーワードで、クラス・構造体の内部でのみ使用することができます。 MeとMyClassが使われる場面と相違点をまとめると次のようになります。
 

        

        
~
|*MeとMyClassの機能と相違点
    End Sub
+
|~機能|>|~相違点|h
+
|~|~Me|~MyClass|h
+
|インスタンス自身のメンバの参照|できる|できる|
+
|隠蔽されたメンバの参照|できる|できる|
+
|コンストラクタの呼び出し|できる|できる|
+
|オーバーライドを無視したメソッドの呼び出し|できない|できる|
+
|インスタンス自身の引渡し|できる|できない|
 

        

        
~
以下でMeとMyClassが使われる個々の場面と、そこでのMe・MyClassの違いについて見ていきます。
End Class
-

          
-
' 派生クラス
-
Public Class DerivedClass
-
    Inherits BaseClass
 

        

        
~
**インスタンス自身のメンバの参照
    ' 派生クラスでのMethod()
~
クラスの外部からメンバ(フィールドやメソッドなど)にアクセスする場合、``&var{変数};.&var{メンバ名};``とします。 これと同様に、クラス内部からメンバにアクセスする場合、``Me.&var{メンバ名};``とします。 このMeはインスタンス自身を表します。 ただ、通常はMeを省略して単に``&var{メンバ名};``とします。
    Protected Overrides Sub Method(ByVal keyword As String)
 

        

        
~
#code(vb){{
        Console.WriteLine("Method of DerivedClass called by " + keyword)
+
Class C
+
  Public Field As Integer = 42
 

        

        
~
  Public Sub Method1()
    End Sub
+
    ' 現在のインスタンス自身のフィールドFieldを参照する
+
    Console.WriteLine(Field)
+

          
+
    ' Meを付けて参照することもできる
+
    Console.WriteLine(Me.Field)
+
  End Sub
+

          
+
  Public Sub Method2()
+
    ' 現在のインスタンス自身のメソッドMethod1を呼び出す
+
    Method1()
+

          
+
    ' Meを付けて参照することもできる
+
    Me.Method1()
+
  End Sub
+
End Class
 

        

        
+
Module Sample
+
  Public Sub Main()
+
    Dim c As New C()
+

          
+
    ' 変数cに代入されているインスタンスのフィールドFieldを参照する
+
    c.Field = 16
+
    ' 変数cに代入されているインスタンスのメソッドMethod1を呼び出す
+
    c.Method1()
+
  End Sub
+
End Module
+
}}
 

        

        
~
構造体の場合も同様にMeでインスタンス自身のメンバを参照できます。
    ' 各キーワードでインスタンスのメソッドを呼び出すためのメソッド
-
    Public Sub CallMethods()
 

        

        
~
#code(vb){{
        ' MyBase による呼び出し
~
Structure S
        MyBase.Method("MyBase")
+
  Public Field As Integer = 42
 

        

        
~
  Public Sub Method1()
        ' MyClass による呼び出し
~
    ' 現在のインスタンス自身のフィールドFieldを参照する
        MyClass.Method("MyClass")
+
    Console.WriteLine(Field)
+

          
+
    ' Meを付けて参照することもできる
+
    Console.WriteLine(Me.Field)
+
  End Sub
+
End Structure
+
}}
 

        

        
~
MeではなくMyClassでインスタンス自身のメンバを参照することもできます。
        ' Me による呼び出し
-
        Me.Method("Me")
 

        

        
~
#code(vb){{
    End Sub
+
Class C
+
  Public Field As Integer = 42
 

        

        
+
  Public Sub Method1()
+
    ' MyClassでインスタンス自身のメンバを参照する
+
    Console.WriteLine(MyClass.Field)
+

          
+
    ' Meでインスタンス自身のメンバを参照する
+
    Console.WriteLine(Me.Field)
+
  End Sub
 
End Class
End Class
+
}}
 

        

        
~
このようにMe・MyClassでインスタンス自身のメンバを参照することを明示できます。 ここまでで紹介した例ではMe・MyClassを省略することもできますが、隠蔽されたメンバを参照する場合はMe・MyClassを明記する必要があります。
' アプリケーションのエントリーポイント
-
Module MeMyclassMybase
-

          
-
    Sub Main()
 

        

        
-
        ' 派生クラスのインスタンスを作成
-
        Dim inst As New DerivedClass()
 

        

        
~
**隠蔽されたメンバの参照
        inst.CallMethods()
+
メソッドがクラスや構造体のフィールド(メンバ変数)と同名の引数をとる場合、そのメソッド内では同名のメンバは''隠蔽''されます。 次の例では、コンストラクタの引数に``x``と``y``があり、この引数が同名のフィールド``x``と``y``を''隠蔽''します。 そのため、``x``と``y``はインスタンスのフィールドではなくコンストラクタの引数``x``と``y``を表すことになります。 この例において、引数``x``と``y``の値はフィールドには代入されず、意図したとおりには初期化されません。
 

        

        
~
#code(vb){{
    End Sub
+
Structure Point
+
  Private x As Integer
+
  Private y As Integer
+

          
+
  Public Sub New(ByVal x As Integer, ByVal y As Integer)
+
    ' 引数xの値をインスタンスのフィールドxに代入したい
+
    x = x
+
    ' 同様に引数yの値をフィールドyに代入したい
+
    y = y
+
  End Sub
+

          
+
  Public Sub Print()
+
    Console.WriteLine("({0}, {1})", x, y)
+
  End Sub
+
End Structure
+

          
+
Module Sample
+
  Public Sub Main()
+
    Dim p As New Point(640, 480)
 

        

        
+
    p.Print()
+
  End Sub
 
End Module
End Module
 
}}
}}
 

        

        
 
#prompt(実行結果){{
#prompt(実行結果){{
~
(0, 0)
Method of BaseClass called by MyBase
-
Method of DerivedClass called by MyClass
-
Method of DerivedClass called by Me
-
Press any key to continue
 
}}
}}
 

        

        
~
このように隠蔽されたメンバは存在しなくなるわけではなく、MeまたはMyClassを使うことで隠蔽されたメンバを参照することができます。
この結果から分かるとおり、MyBaseはそのインスタンスの基底クラスのメンバを参照しているのに対し、MyClass及びMeはそのインスタンス自身のクラスのメンバを参照していることがわかります。 では、MyClassとMeは同じものといえるのでしょうか。 下位互換性のためにMeが残されたのでしょうか。 それともキーワードが二つあるからには何らかの違いがあるのでしょうか。
-

          
-
*MeとMyClassの違い
-
実際のところ、全く意味の同じキーワードが二種類存在するのは下位互換性のためだけではなく、ちゃんとした違いがあります。 ほとんどの機能はMeも MyClassも大差ないのですが、メソッドの呼び出しの時にはその違いがあらわれます。 その違いがあらわれるようなサンプルコードを次に示します。
 

        

        
 
#code(vb){{
#code(vb){{
~
Structure Point
Imports System
+
  Private x As Integer
+
  Private y As Integer
+

          
+
  Public Sub New(ByVal x As Integer, ByVal y As Integer)
+
    ' 引数xの値をインスタンスのフィールドxに代入する
+
    Me.x = x
+
    ' 引数yの値をインスタンスのフィールドyに代入する
+
    Me.y = y
+

          
+
    ' MyClassでも隠蔽されたメンバを参照することができる
+
    MyClass.x = x
+
    MyClass.y = y
+
  End Sub
+

          
+
  Public Sub Print()
+
    Console.WriteLine("({0}, {1})", x, y)
+
  End Sub
+
End Structure
+
}}
 

        

        
~
引数の場合のほかにも、ローカル変数の場合でも同名のメンバが隠蔽されます。 この場合でも、Me・MyClassを使うことでローカル変数に隠蔽されたメンバを参照することができます。
' 基底クラス
-
Public Class BaseClass
 

        

        
~
#code(vb){{
    ' 基底クラスでのMethod()
~
Structure Point
    Protected Overridable Sub Method(ByVal keyword As String)
+
  Private x As Integer
+
  Private y As Integer
+

          
+
  Public Sub Test()
+
    ' フィールドと同名のローカル変数を宣言する
+
    Dim x As Integer = 16
+
    Dim y As Integer = 42
+

          
+
    ' ローカル変数のx, yの値が表示される
+
    Console.WriteLine(x)
+
    Console.WriteLine(y)
+

          
+
    ' インスタンスのフィールドx, yの値が表示される
+
    Console.WriteLine(Me.x)
+
    Console.WriteLine(Me.y)
+
    Console.WriteLine(MyClass.x)
+
    Console.WriteLine(MyClass.y)
+
  End Sub
+
End Structure
+
}}
 

        

        
~
MeやMyClassを使って隠蔽されたメンバを参照するよりも、メンバ名と同名の引数名・変数名を付けることを避けたほうが分かりやすく、無難です。
        Console.WriteLine("Method of BaseClass called by " + keyword)
 

        

        
-
    End Sub
 

        

        
~
**コンストラクタの呼び出し
    ' 各キーワードでインスタンスのメソッドを呼び出すためのメソッド
~
コンストラクタでは、引数の異なる別のコンストラクタを呼び出すことができます。 この場合、メソッド呼び出しのようにコンストラクタを直接``New(...)``として呼び出すことはできません。 必ずMeもしくはMyClassを伴って``Me.New(...)``や``MyClass.New(...)``のように呼び出す必要があります。
    Public Sub CallMethods()
 

        

        
~
#code(vb){{
        ' MyClass による呼び出し
~
Class Account
        MyClass.Method("MyClass")
+
  ' この二つのフィールドは必須としたい
+
  Public Name As String
+
  Public ID As Integer
+
  ' このフィールドは省略可能としたい
+
  Public MailAddress As String
+

          
+
  ' 必須のパラメータのみを指定するコンストラクタ
+
  Public Sub New(ByVal name As String, ByVal id As Integer)
+
    ' 省略されたパラメータのデフォルトとしてNothingを指定して別のコンストラクタを呼び出す
+
    Me.New(name, id, Nothing)
+

          
+
    ' Meの代わりにMyClassを使ってコンストラクタを呼び出すこともできる
+
    'MyClass.New(name, id, Nothing)
+
  End Sub
+

          
+
  ' 省略可能なパラメータも指定可能なコンストラクタ
+
  Public Sub New(ByVal name As String, ByVal id As Integer, ByVal mailAddress As String)
+
    Me.Name = name
+
    Me.ID = id
+
    Me.MailAddress = mailAddress
+
  End Sub
+
End Class
+
}}
 

        

        
-
        ' Me による呼び出し
-
        Me.Method("Me")
 

        

        
~
**オーバーライドを無視したメソッドの呼び出し
    End Sub
+
クラスを継承してメソッドをオーバーライドすると、基底クラスのメソッドの動作を変更することができます。 基底クラス内からオーバーライド可能なメソッドを呼び出す場合、派生クラスでメソッドがオーバーライドされていれば、そのメソッドが呼び出されます。
 

        

        
+
#code(vb,オーバーライドされたメソッドを呼び出す例){{
+
' 基底クラス
+
Class BaseClass
+
  Public Sub CallMethod()
+
    ' オーバーライドされている可能性のあるメソッドを呼び出す
+
    Method()
+
  End Sub
+

          
+
  ' 派生クラスでオーバーライド可能なメソッド
+
  Protected Overridable Sub Method()
+
    Console.WriteLine("BaseClass")
+
  End Sub
 
End Class
End Class
 

        

        
 
' 派生クラス
' 派生クラス
~
Class DerivedClass
Public Class DerivedClass
~
  Inherits BaseClass
    Inherits BaseClass
-

          
-
    ' 派生クラスでのMethod()
-
    Protected Overrides Sub Method(ByVal keyword As String)
 

        

        
~
  ' 基底クラスのメソッドをオーバーライドして動作を変更したメソッド
        Console.WriteLine("Method of DerivedClass called by " + keyword)
+
  Protected Overrides Sub Method()
+
    Console.WriteLine("DerivedClass")
+
  End Sub
+
End Class
 

        

        
~
Module Sample
    End Sub
+
  Public Sub Main()
+
    ' 派生クラスのインスタンスを作成
+
    Dim i As New DerivedClass()
+

          
+
    ' オーバーライドされているメソッドを呼び出す
+
    i.CallMethod()
+
  End Sub
+
End Module
+
}}
 

        

        
~
#prompt(実行結果){{
End Class
+
DerivedClass
+
}}
 

        

        
~
MeおよびMyClassを使ってオーバーライドされているメソッドを呼び出す場合、両者は同じ動作とはならない点に注意が必要です。 Meキーワードでオーバーライドされているメソッドを呼び出す場合は、Meを省略して呼び出した場合と同じく''派生クラスでオーバーライドされた方のメソッド''が呼び出されますが、MyClassキーワードでは''MyClassが使用されたクラスのメソッド''が呼び出されます。
' アプリケーションのエントリーポイント
-
Module MeMyclassMybase
 

        

        
~
#code(vb,MeとMyClassで呼び出されるメソッドの違い){{
    Sub Main()
+
Imports System
+
Imports System.Collections.Generic
 

        

        
~
' 基底クラス
        ' 派生クラスのインスタンスを作成
~
Class BaseClass
        Dim inst As New DerivedClass()
+
  Public Sub CallMethodByMe()
+
    ' Meを使ってオーバーライドされている可能性のあるメソッドを呼び出す
+
    Me.Method()
+
  End Sub
+

          
+
  Public Sub CallMethodByMyClass()
+
    ' MyClassを使ってオーバーライドされている可能性のあるメソッドを呼び出す
+
    MyClass.Method()
+
  End Sub
+

          
+
  ' 派生クラスでオーバーライド可能なメソッド
+
  Protected Overridable Sub Method()
+
    Console.WriteLine("BaseClass")
+
  End Sub
+
End Class
 

        

        
~
' 派生クラス
        inst.CallMethods()
+
Class DerivedClass
+
  Inherits BaseClass
 

        

        
~
  ' 基底クラスのメソッドをオーバーライドして動作を変更したメソッド
    End Sub
+
  Protected Overrides Sub Method()
+
    Console.WriteLine("DerivedClass")
+
  End Sub
+
End Class
 

        

        
+
Module Sample
+
  Public Sub Main()
+
    ' 派生クラスのインスタンスを作成
+
    Dim i As New DerivedClass()
+

          
+
    ' Meを使ってオーバーライドされているメソッドを呼び出す
+
    i.CallMethodByMe()
+

          
+
    ' MyClassを使ってオーバーライドされているメソッドを呼び出す
+
    i.CallMethodByMyClass()
+
  End Sub
 
End Module
End Module
 
}}
}}
 

        

        
 
#prompt(実行結果){{
#prompt(実行結果){{
~
DerivedClass
Method of BaseClass called by MyClass
~
BaseClass
Method of DerivedClass called by Me
-
Press any key to continue
 
}}
}}
 

        

        
~
Meではメソッドの''オーバーライドが有効になる''のに対し、MyClassでは''オーバーライドが無視される''と見ることができます。 言い換えると、Meでは''オーバーライドの影響を受ける''のに対し、MyClassでは''オーバーライドの影響を受けない''、となります。
今回は先ほどとは異なり、CallMethods()を基底クラスに配置しました。 そして、派生クラスDerivedClassのインスタンスを作成し、そのインスタンスからCallMethods()を呼び出しています。 結果を見てわかるとおり、MeとMyClassでは異なる文字列を出力していることがわかります。 つまり、Me.Method()はDerivedClass.Method()を呼び、MyClass.Method()は BaseClass.Method()を呼び出しています。
 

        

        
~
もしくは、Meではインスタンス自身(=Me)が派生クラスかどうかを考慮してメソッド呼び出しを行うのに対し、MyClassでは常に自分のクラス(=MyClass)のメソッドを呼び出すと見ることもできます。
これは何を意味しているかというと、MyClassはインスタンスのクラスがどのクラスであるかに関わらず、確実にMyClassが用いられたクラスのメソッドを呼び出しているのに対し、Meの場合はMeが用いられたクラスが何であるかに関わらず、インスタンスのクラスのメソッド、つまり派生クラスでオーバーライドされたメソッドを呼び出していることになります。
 

        

        
~
なお、コンストラクタ(Newメソッド)も一種のメソッドとみなされますが、コンストラクタはオーバーライドできないためMeとMyClassのどちらを使って呼び出しても動作が変わることはありません。
さらに、派生クラスで基底クラスのメソッドをシャドウするとその挙動は変化します。 次のコードはそれを行ったものです(DerivedClass.Method()のOverridesキーワードをShadowsキーワードに変えています)。
+

          
+

          
+
**インスタンス自身の引渡し
+
RaiseEventによってイベントを発生させる場合や、メソッドの引数としてインスタンス自身を渡す場合にはMeを使います。 MyClassではインスタンス自身を引き渡すことはできません。
 

        

        
 
#code(vb){{
#code(vb){{
~
Class Control
Imports System
+
  Public Event Click As EventHandler
+

          
+
  Private Sub OnClick(ByVal sender As Object, ByVal e As EventArgs)
+
    ' Clickイベントを発生させる
+
    RaiseEvent Click(sender, e)
+
  End Sub
+

          
+
  Public Sub RaiseClick()
+
    ' イベント発生源として自分自身のインスタンスを渡してイベントを発生させる
+
    OnClick(Me, EventArgs.Empty)
+

          
+
    ' 自分自身のインスタンスを渡す目的でMyClassを使用することはできない
+
    OnClick(MyClass, EventArgs.Empty)
+
    ' error BC32028: 'MyClass' の後には '.' および識別子を指定しなければなりません。
+
  End Sub
+
End Class
+
}}
 

        

        
-
' 基底クラス
-
Public Class BaseClass
 

        

        
~
**MeとMyClassの違いと使い分け
    ' 基底クラスでのMethod()
~
このようにMeとMyClassは機能や役割が似ていますが、全く同じではないため正しく使い分ける必要があります。 Meではクラス外部からメンバを参照する場合と同じように実際のインスタンスの型が考慮される動作となるのに対し、MyClassでは参照するメンバをインスタンスの型に関わらず現在のクラスに限定する動作となります。
    Protected Overridable Sub Method(ByVal keyword As String)
 

        

        
~
MeとMyClassの使い分けを整理すると次のようになります。
        Console.WriteLine("Method of BaseClass called by " + keyword)
 

        

        
~
+インスタンス自身を引数として渡す場合は''Me''
    End Sub
+
+オーバーライドを無視して自クラスのメソッドの呼び出しを行う場合は''MyClass''
+
+オーバーライドされないメンバや隠蔽されたメンバを参照する場合は''MeでもMyClassでも可''
 

        

        
~
VBのMeキーワードとMyClassキーワードはC#における``this``にほぼ相当するものですが、C#の``this``ではオーバーライドを無視して自クラスのメソッドを呼び出すことはできません。 このようなMyClassの動作はVB固有の動作です。
    ' 各キーワードでインスタンスのメソッドを呼び出すためのメソッド
-
    Public Sub CallMethods()
 

        

        
-
        ' MyClass による呼び出し
-
        MyClass.Method("MyClass")
 

        

        
~
*MyBase [#MyBaseKeyword]
        ' Me による呼び出し
~
MyBaseは基底クラスのメンバを参照する際に使用します。 派生クラスからは``MyBase.&var{メンバ};``とすることで基底クラスのメンバを参照することができます。 ただ、MeやMyClassと同様にMyBaseを省略しても基底クラスから継承されたメンバを参照することはできます。
        Me.Method("Me")
 

        

        
~
メソッドがオーバーライド(``Overrides``)または隠蔽(``Shadows``)されることにより基底クラスの実装が隠されている場合には、MyBaseを明記して呼び出す必要があります。
    End Sub
+

          
+
#code(vb){{
+
Class Control
+
  Public Event Click As EventHandler
 

        

        
+
  Protected Overridable Sub OnClick(ByVal e As EventArgs)
+
    ' Clickイベントを発生させる
+
    RaiseEvent Click(Me, e)
+
  End Sub
+

          
+
  Public Sub RaiseClick()
+
    OnClick(EventArgs.Empty)
+
  End Sub
 
End Class
End Class
 

        

        
~
Class Button
' 派生クラス
~
  Inherits Control
Public Class DerivedClass
~

          
    Inherits BaseClass
+
  Public Enabled As Boolean
+

          
+
  ' メソッドをオーバーライドしてOnClickメソッドの動作を変える
+
  Protected Overrides Sub OnClick(ByVal e As EventArgs)
+
    ' EnabledがTrueの場合のみ、基底クラスのOnClickメソッドを呼び出してClickイベントを発生させる
+
    If Enabled Then MyBase.OnClick(e)
+
  End Sub
+
End Class
+
}}
+

          
+
コンストラクタから基底クラスのコンストラクタを呼び出す場合も、MyBaseを明記します。
 

        

        
~
#code(vb){{
    ' 派生クラスでのMethod()
~
Class Control
    Protected Shadows Sub Method(ByVal keyword As String)
+
  Public Parent As Control
+

          
+
  Public Sub New(ByVal parent As Control)
+
    Me.Parent = parent
+
  End Sub
+
End Class
 

        

        
~
Class Button
        Console.WriteLine("Method of DerivedClass called by " + keyword)
+
  Inherits Control
 

        

        
~
  Public Sub New(ByVal parent As Control)
    End Sub
+
    ' 基底クラスのコンストラクタを呼び出して初期化する
+
    MyBase.New(parent)
 

        

        
+
    ' 必要に応じて追加の初期化処理を記述する
+
  End Sub
 
End Class
End Class
+
}}
+

          
+
派生クラスで基底クラスと同名のフィールドを宣言した場合も、基底クラス側のフィールドが隠蔽されます。 隠蔽された基底クラスのフィールドを参照する場合にもMyBaseを明記します。
 

        

        
~
#code(vb){{
' アプリケーションのエントリーポイント
~
Class BaseClass
Module MeMyclassMybase
+
  Public Field As Integer
+
End Class
 

        

        
~
Class DerivedClass
    Sub Main()
+
  Inherits BaseClass
 

        

        
~
  ' 基底クラスで宣言されているものと同名のフィールド
        ' 派生クラスのインスタンスを作成
~
  Public Field As Integer
        Dim inst As New DerivedClass()
 

        

        
~
  Public Sub Print()
        inst.CallMethods()
+
    ' 基底クラスのFieldを参照する
+
    MyBase.Field = 42
+

          
+
    ' このクラスのFieldを参照する
+
    Field = 3
+

          
+
    Console.WriteLine(MyBase.Field)
+
    Console.WriteLine(Field)
+
  End Sub
+
End Class
 

        

        
~
Module Sample
    End Sub
+
  Public Sub Main()
+
    Dim i As New DerivedClass()
 

        

        
+
    i.Print()
+
  End Sub
 
End Module
End Module
 
}}
}}
 

        

        
 
#prompt(実行結果){{
#prompt(実行結果){{
~
42
Method of BaseClass called by MyClass
~
3
Method of BaseClass called by Me
-
Press any key to continue
 
}}
}}
 

        

        
~
VBのMyBaseキーワードはC#における``base``にほぼ相当するものです。
今度はMeもMyClassもBaseClass.Method()を呼び出しています。 このように、メソッドの呼び出しではMeとMyClassは多少挙動が異なるので注意が必要です。 通常の使用方法ならMyClassを用いた方がよけいなバグを生じる可能性は少ないと思います(しかし、VB時代からの習慣で、ついMeを使いたくなってしまいますが・・・)。
+

          
+

          
+
*My名前空間 [#MyNamespace]
+
VBではMe・MyClass・MyBaseの他にも似た名前を持つもとしてMy名前空間といものが存在します。 My名前空間はVB8(VB2005)から導入されたもので、様々な機能や情報へのショートカットを提供するものです。 そのため、Me・MyClass・MyBaseの各キーワードとMy名前空間は全く役割が異なります。
+

          
+
#code(vb,My名前空間の使用例){{
+
Module Sample
+
  Public Sub Main()
+
    ' 現在ログインしているユーザの名前を取得する
+
    Console.WriteLine(My.User.Name)
+

          
+
    ' コンピュータの名前を取得する
+
    Console.WriteLine(My.Computer.Name)
+

          
+
    ' ファイルが存在しているか調べる
+
    Dim file As String = "E:\sample.txt"
+

          
+
    If My.Computer.FileSystem.FileExists(file)
+
      Console.WriteLine("ファイル{0}は存在します", file)
+
    Else
+
      Console.WriteLine("ファイル{0}は存在しません", file)
+
    End If
+
  End Sub
+
End Module
+
}}
+

          
+
My名前空間については[[programming/vb.net/diff_7.xto8/07_my_namespace]]をご覧ください。
+

          
+