Visual Basic 初級講座 [改訂版]
VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

第7回 クラスを使う仕組み

2020/3/7

この記事が対象とする製品・バージョン

VB2019 Visual Basic 2019 対象です。
VB2017 Visual Basic 2017 対象です。
VB2015 Visual Basic 2015 対象です。
VB2013 Visual Basic 2013 対象です。
VB2012 Visual Basic 2012 対象です。
VB2010 Visual Basic 2010 対象です。
VB2008 Visual Basic 2008 対象です。
VB2005 Visual Basic 2005 対象です。
VB.NET 2003 Visual Basic.NET 2003 対象外ですがほとんどの説明があてはまるので参考になります。
VB.NET 2002 Visual Basic.NET (2002) 対象外ですがほとんどの説明があてはまるので参考になります。
VB6対応 Visual Basic 6.0 × 対象外です。

 

目次

 

 

1.モジュール

前回はクラスと構造体のメンバーの呼び出し方の基本的なルールを説明しました。

今回はいくつかの例外と、注意点を説明します。

 

1つ目は「モジュール」と呼ばれる例外です。

モジュールとはクラスの一種です。下記の点で特殊な存在です。

すべてのメンバーが共有メンバーなのでインスタンスを作成する必要がありません。そのためそもそもインスタンスが作成できないようになっています。

最大の特徴はクラス名(モジュール名)を記述せずにメンバー名だけで呼び出しができる点です。

メモ メモ  -  名前空間の省略
呼び出し時の名前空間の省略可否は、第5回 クラスと名前空間 3-3.名前空間の省略で説明している通り、設定により変わります。設定はWindowsフォームアプリケーションやコンソールアプリケーションなどアプリケーションの種類により初期値が異なる場合もあるので、これから説明するプログラム例を実際に試すと名前空間を省略できないためエラーになる場合があるかもしれません。
この回で紹介するサンプルは特記のない限り.NET FrameworkによるWindowsフォームアプリケーションでそのまま試すことができることを確認しています。

通常のクラスの共有メンバーは呼び出す場合に クラス名.共有メンバー名 と記述します。たとえば、MathクラスのSqrtメソッドは次のように呼び出せるのでした。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'196の平方根を取得します。
Dim root As Double = Math.Sqrt(196)

この場合、クラス名である Math を省略することはできません。

一方、モジュールの場合はクラス名(モジュール名)を省略して、いきなりそのメンバーを呼び出せます。

下記の例はInformationモジュール(読み方:Information = インフォメーション)のTypeNameメソッド(読み方:TypeName = タイプネーム)の呼び出しです。

Informationモジュールの名前は一切登場しません。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'resultは "Integer" になります。
Dim result As String = TypeName(12345)

なお、Information.TypeNameメソッドは変数やリテラルなどの型の名前を返すメソッドですので、上記の例では 12345 の型である "Integer" という名前を文字列で取得できます。

 

もしそうしたければ、通常の共有メソッドのようにクラス名(モジュール名)を書いて呼び出すことも可能です。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'resultは "Integer" になります。
Dim result As String = Information.TypeName(12345)

 

Visual Basicでははじめから下記のモジュールが使用できるようになっています。

.NET Core上で動作するVBの場合、言語仕様が少し変わっており、この中で利用できない機能もあります。

モジュール 読み方 機能 使用してよい?
Constants コンスタンツ (VBで定義されている定数の集まり。) △ お勧めはしませんが、必要ならば。
Conversion コンバージョン 伝統的な値の変換・型変換。 × 使用しないことをお勧めします。
DateAndTime デイトアンドタイム 日付を時刻の操作。 × Now以外は使用しないことをお勧めします。
FileSystem ファイルシステム 伝統的なファイル・フォルダーの処理。 × 使用しないことをお勧めします。
Financial ファイナンシャル 財務関連の処理。 △ お勧めはしませんが、必要ならば。
Globals グローバルズ 使用しているVBのバージョン情報 △ お勧めはしませんが、必要ならば。
Information インフォメーション 変数や値の情報を取得・操作します。 × 使用しないことをお勧めします。
Interaction インタラクティブ システムやユーザーと対話します。 △ 使いどころによります。
Strings ストリングス 文字列の処理 △ 使いどころによります。
VBMath ブイビーマス 乱数の処理 × 使用しないことをお勧めします。

「Strings」モジュールは、文字列型を表す「String」に名前がよく似ていますが、末尾に s がついているという違いがあります。

これらのモジュールの機能は、.NET登場以前の1998年頃の古いVB時代の機能をそのまま(あるいは、少し名前や形を変えて)移植したものであり、古いVBとの互換性を重視する場合には使用する価値がありますが、そうでない場合にはほとんど使用する価値がありません。

これらのモジュールが提供する機能のほとんどは.NET Frameworkや.NET Coreでも提供されているので、モジュールの機能を使うよりはフレームワークの機能を使ったほうが良いからです。

 

モジュールが提供する機能の中で今(2020年現在)でも私が使用することがあるのは次の8個くらいです。(配列やCOMなど初級講座で登場していない機能もあります)。

モジュール メンバー 機能 同じようなことを実現/表現するフレームワークの機能
Constants vbNewLine 改行文字列を表します。 Environment.NewLine
Constants vbTag タブ文字を表します。 Convert.ToChar(Keys.Tab)
DateAndTime Now 現在の日時を表します。 DateTime.Now
Information UBound 配列のインデックスの最大値を取得します。 配列の Length プロパティ (※UBoundより 1多い数値を返します。)
Interaction CreateObject COMのインスタンスを生成します。 Type.GetTypeFromProgId
Interaction MsgBox メッセージを表示し、ユーザーの選択を返します。 MessageBox.Show
Strings Len 文字列の長さを取得します。 String.Length (非共有メンバー)
Strings Trim 文字列の前後のスペースを除去します。 String.Trim (非共有メンバー)

これらの機能のほとんどはモジュールを使わなくても実現できるので、モジュールを一切使わないというプログラマーもいることでしょう。

対応するフレームワークの機能も表に書いておきました。モジュールを使わない場合の代替となる機能ですが、まったく同じ処理や結果ではない場合が多いので注意してください。

モジュールの機能の中で特筆すべきは MsgBox です。初級講座でも何度も登場していますが、メッセージを表示するという簡単な機能です。フレームワークの機能にはこれほど簡単にメッセージを表示できる機能がないので私は重宝しています。WindowsフォームアプリケーションであればMessageBox.Showを使ってほとんど同じことができるのですが、それ以外のアプリケーションの場合は、簡単に代替できる手段がありません。MsgBox はどのようなタイプのアプリケーションでも無節操にメッセージを表示するという常識破りの機能で、私にはとても便利です。この常識破りの機能を汎用的に再現するのが難しいことと、本来メッセージを表示すべきでないシーンでもメッセージを表示できてしまい初心者には使いどころが難しい面があるため、.NET Coreでは使用できなくなりました。

 

2.構造体

2-1.構造体のインスタンス

基本的なルールでは非共有メンバーはインスタンスを経由して呼び出すということは既に説明しました。

そして、インスタンスを作るにはコンストラクターを呼び出せばよいこと、コンストラクラーを呼び出すには New キーワードを使用するということも説明しました。

例外的に構造体の場合、インスタンスを作成するために New は不要です。コンストラクターは自動的に呼び出されインスタンスが作成されます。

次のプログラムは四角形を現すRectangle構造体を使って、2つの四角形の重なっている部分の大きさを計算します。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'▼1つ目の四角形
Dim rect1 As Rectangle
rect1.X = 0
rect1.Y = 0
rect1.Width = 100
rect1.Height = 100

'▼2つ目の四角形
Dim rect2 As Rectangle
rect2.X = 80
rect2.Y = 70
rect2.Width = 60
rect2.Height = 60

'▼重なっている部分
Dim sharedRect As Rectangle
sharedRect = Rectangle.Intersect(rect1, rect2)

'{X=80,Y=70,Width=20,Height=30}
MsgBox(sharedRect.ToString)

このプログラムでX, Y, Width, Height の各プロパティは非共有プロパティですが、New でインスタンスを作成せずに呼び出すことができています。

構造体のインスタンスを作るのに New は不要ということです。

不要でも、わかりにくいのであえて New をつけることもできます。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019


Dim
rect1 As New Rectangle

このプログラムは有効ですが、Newには何の意味もありません。

 

引数つきのコンストラクターを使用したい場合には、自動的にコンストラクターを呼び出すのではなく、明示的にコンストラクターを呼び出したい場合があります。

そのときは New を使います。

Rectangleクラスの場合、引数付きのコンストラクターを使うと座標を簡単に指定できるので、さきほどのプログラムはこのように短く書くことができるようになります。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'▼1つ目の四角形
Dim rect1 As New Rectangle(0, 0, 100, 100)

'▼2つ目の四角形
Dim rect2 As New Rectangle(80, 70, 60, 60)

'▼重なっている部分
Dim sharedRect As Rectangle
sharedRect = Rectangle.Intersect(rect1, rect2)

'{X=80,Y=70,Width=20,Height=30}
MsgBox(sharedRect.ToString)

なお、重なっている部分を計算するIntersectメソッド(読み方:Intersect = インターセクト)はインスタンスを返す仕様です。

 

構造体かクラスかで扱いを変えるのも面倒なので、インスタンスが必要な場合には常に New をつけることを習慣にするのも良いでしょう。

 

クラスと構造体のこのような違いは、構造体は「値」を表すためのものであり、値はたまたま数字が同じでも別物である。という思想があります。

たとえば、山田君の身長が 160cm で、鈴木君の身長も 160cm だったとします。どちらも 160cm ですが、片方は山田君の身長であり、もう片方は鈴木君の身長であり同じ別のものだ。という考え方です。

※もちろん、160cm という数字自体には個性はなく同じものだ と考える考え方もあります。ここで説明したいのは構造体の考え方はそうではないということです。

 

2-2.構造体の扱い

もう1つ構造体に関連して話が面倒な例を紹介しておきます。

Windowsフォームアプリケーションでフォームの座標はLocationプロパティ(読み方:Location = ロケーション)で表されています。このLocationプロパティは Point型 であり、X座標とY座標を持っています。

Pointは構造体です。

そこで、フォームの位置を指定するプログラムを書く場合、思わず次のように書いてしまいそうですが、このプログラムは間違いです。

※フォーム内では Me と書くことでフォーム自身を意味しています。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019


Me
.Location.X = 0

VB2005あたりからこのプログラムをエラーにして実行できないようにしてくれるので間違いに気がつけるのですが、VB.NET2002の頃はこのプログラムはエラーにならずに実行することができました。でも実行してもフォームの位置がまったく変わらないので首をかしげるプログラマーが続出したというわけです。

このプログラムではLocationプロパティが表す構造体のコピーが作られ、そのコピーのXプロパティを0に設定するという意味になります。コピーの値を変更しているだけなので本体の値は変わらずに何もおきません。

 

要するに、上記のプログラムはこのプログラムと同じ意味です。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'フォームのLocationのコピーを取得する。
Dim newLocation As Point = Me.Location

'コピーのX座標を 0 にする。
newLocation.X = 0

コピーに対して値を設定しているだけだということです。

 

これは構造体に特有の現象で、クラスの場合は、コピーではなく本体を直接操作できるのでこのようなややこしいことは発生しません。(これは「値型・参照型」というトピックです。詳しく知りたい方は調べてみてください。初級講座でも別途扱う予定です。)

正直、この理屈はなかなか難しいです。ここの説明が理解できずに困惑している方もいることでしょう。でも、心配しないでください。もし、まちがったことをしてしまってもVBはちゃんとそれをエラーであると指摘してくれるからです。

この例では正しく座標を変更したければ次のように記述します。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'フォームのLocationのコピーを取得する。
Dim newLocation As Point = Me.Location

'コピーのX座標を 0 にする。
newLocation.X = 0

'フォームのLocationにコピーした値を設定する。
Me.Location = newLocation

 

3.名前の衝突

3-1.近くの名前の優先

変数や定数など自分で定義できる名前にはVBの予約語(VBであらかじめ用意されているキーワード)以外は自由な名前をつけられるため、たまたまクラス名やモジュール名、モジュールのメンバー名や名前空間の名前などと同じ名前をつけてしまうことがあります。

同じ名前がついている定義が複数ある場合、近くで定義されている方が優先され、その他の定義は名前だけでは参照できなくなります。この現象をシャドウ、シャドウィングと呼びます。

メモ メモ  -  「近く」?
「近く」を厳密に定義するには現段階では知識が不足しています。そのうえ、ほとんどの場合、私たちが感覚的に「近い」「遠い」と思うものと一致しているためこの定義を厳密に行わなくても特に困ることはありません。
公式の説明はここにあります。
https://docs.microsoft.com/ja-jp/dotnet/visual-basic/programming-guide/language-features/declared-elements/shadowing

 

たとえば、Clipboardという名前の変数がある場合、クリップボードに文字列をコピーする Clipboardクラスの SetText メソッドは呼び出せなくなります。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'この例はエラーです。
Dim Clipboard As Integer
Clipboard.SetText("ABC")

近くにClipboardという変数があるので、「Clipboard」という記述がClipboardクラスではなくClipboard変数と解釈されるためです。

 

この場合、次のように名前空間から指定すれば変数ではないことが明確になるため正常に呼び出せます。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Dim Clipboard As Integer
System.Windows.Forms.Clipboard.SetText("ABC")

 

ところが、運悪く System という名前の変数が存在する場合はこの手も使えなくなります。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Dim Clipboard As Integer
Dim System As Integer

System.Windows.Forms.Clipboard.SetText("ABC")

 

変数の名前を変えられれば簡単なのですが、チームで開発していたり、他の会社が開発した機能を呼び出していたり、VB以外の言語と連携していたり、本格的なプログラム開発は複雑なので、なかなか定義されている名前を変更できないということがあるのです。

この場合、VBの予約語である Global (読み方:Global = グローバル)を頭につけることで、System を名前空間と認識させることができます。

 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Dim Clipboard As Integer
Dim System As Integer

Global.System.Windows.Forms.Clipboard.SetText("ABC")

Globalは予約語なので、これと同じ名前の変数などの定義を作成することはできません。これでこの問題は最終的に解決するというわけです。

※万一、VB以外の言語と連携しているなどの理由で、どこかで Global という定義が作成されている場合でも、VBにとって、Global は予約語であるため、VB内でその定義を参照するには [ ] を付けて [Global] と記述する必要があります。そのため、予約語であるGlobalとVB外で定義されている[Global]の区別が可能です。

 

参考:Visual Basic における名前空間

https://docs.microsoft.com/ja-jp/dotnet/visual-basic/programming-guide/program-structure/namespaces?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev16.query%3FappId%3DDev16IDEF1%26l%3DJA-JP%26k%3Dk(vb.Global)%3Bk(TargetFrameworkMoniker-.NETFramework%2CVersion%3Dv4.7.2)%3Bk(DevLang-VB)%26rd%3Dtrue

 

 

3-2.Windowsフォームアプリケーションの注意

Windowsフォームアプリケーションでフォームにプログラムしている場合は、フォームで定義されているメソッドやプロパティの名前が他で定義されている名前と同じになっている場合がありシャドウが発生します。

有名なのはLeftとRightです。

WindowsフォームアプリケーションではLeftとRightはフォームの左側の位置と右側の位置を表すプロパティです。

一方、Stringsモジュールには文字列の左側から何文字かを抜き出すLeftメソッドと、右側から何文字かを抜き出すRightメソッドが定義されています。

これらは良く使われるメソッドですが、Windowsフォームアプリケーションでフォームのプログラム内で使用する場合は、ただ単にLeft、Rightと記述するとフォームのプロパティの方の意味になってしまうので、モジュール名を省略することができません。

たとえば、コンソールアプリケーションであれば、次のようにしてStringsモジュールのLeftメソッドを使用できます。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'「あいうえお」の左3文字を切り抜いてvalueに代入
Dim value As String = Left("あいうえお", 3)

'「あいう」と表示されます。
Console.WriteLine(value)

これと同じプログラムをWindowsフォームアプリケーションのフォーム内のプログラムに記述するとエラーになります。

Leftメソッド呼び出し時にモジュール名を明示して Strings. を追加すれば名前の衝突が回避できるのでフォーム内でもLeftメソッドを使用できます。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'「あいうえお」の左3文字を切り抜いてvalueに代入
Dim value As String = Strings.Left("あいうえお", 3)

'「あいう」と表示されます。
MsgBox(value)

コンソールアプリケーションの場合でも、Leftと書く代わりにStrings.Left と書いても良いので、Strings. をつける書き方の方が汎用性はあります。

 

なお、これと同じ機能はフレームワークのString.Substringメソッドでも実現できます。このメソッドはStringクラスのメンバーであるという性質上名前が衝突して呼び出せないという事態はまず考えられません。Windowsフォームアプリケーションでもコンソールアプリケーションでも同じように呼び出せます。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'「あいうえお」の左3文字を切り抜いてvalueに代入
Dim value As String = "あいうえお".Substring(0, 3)

'「あいう」と表示されます。
Console.WriteLine(value)

 

 

4.参照設定

4-1.参照設定

Microsoft Docsに記載の.NET Framework.NET Coreのライブラリには大量のクラスが並んでいます。

これらの機能は、拡張子がDLLの複数のファイルに分かれて実装されており、VBから呼び出すにはまず使いたいDLLファイルを選ぶ必要があります。

このようにプログラムとして呼び出したい外部ファイルを選ぶことを「参照設定」と呼びます。

参照設定できるファイルにはいろいろな種類がありますが、.NETの技術でできている呼び出し可能なファイルは「アセンブリ」と呼ばれます。

たとえば、Windowsにクリップボードにコピー・貼り付け等できる機能を提供するClipboardクラスは、アセンブリ欄に System.Windows.Forms.dll と書いてあります。

つまり、Clipboardクラスを使いたければ、System.Windows.Forms.dllに参照設定をする必要があるということです。

現在、参照設定されているアセンブリ等を確認するには、プロジェクトのプロパティの参照設定ページを確認します。

プロジェクトのテンプレートでは、よく使いそうな機能ははじめから参照設定されているので、この設定を確認すると既にいくつかのアセンブリが存在していることを確認できるでしょう。

Windowsフォームアプリケーションのテンプレートでは System.Windows.Forms.dllがはじめから参照設定されてるので、Clipboardクラスは何もしなくても使用できます。

※そのうえ、プロジェクトレベルのインポート設定で System.Windows.Forms名前空間は省略可能になっているため、プログラム内で Clipboard. と書くといきなりClipboardクラスの共有メンバーが呼び出せるというわけです。

 

もっとも基本的なアセンブリである、mscorlib.dll だけは何もしなくても自動的に参照されます。このアセンブリにはStringやIntegerのような型など基本的なクラス・構造体等が含まれています。

これ以外の参照設定されていないアセンブリに含まれるクラスや構造体などはプログラムをどんなに工夫しても通常は呼び出すことはできません。

発展 発展学習  -  通常でない場合

発展学習では意欲的な方のために現段階では特に理解する必要はない項目を解説します。

プラグインのようにプログラム時点では存在しなかった機能を呼び出せるようにする仕組みもあります。たとえば、Activatorクラス(読み方:Activator = アクティベーター)は、アセンブリと型を文字列の引数で指定することで、参照設定していないDLLを読み込んで内部に含まれるクラスのインスタンスを作成することができます。

https://docs.microsoft.com/ja-jp/dotnet/api/system.activator.createinstance?view=netframework-4.8#System_Activator_CreateInstance_System_String_System_String_

私はこのような機能は「通常」とは言えません。便利ではありますが。原則論はやはり「参照設定していない機能は呼び出せない」です。

学校の授業を思い出してください。中学校のとき、「xの2乗が -4 になるとき、x は何でしょう?」という問題がでたら答えは「解なし」でしたよね。「2乗してマイナスになる数はありえない」という原則論があったからです。ところが、高校になって、数の概念が虚数に拡張されると、同じ問題の答えは「2i (i は虚数単位)」になりましたよね。原則論あっての拡張なんです。

 

4-2.参照設定の方法

.NET Frameworkの場合

参照設定を追加する操作方法は.NET Frameworkを使用している場合と、.NET Coreを使用している場合で違います。

 

.NET Frameworkの場合、ソリューションエクスプローラーでプロジェクトを右クリックして、[追加] - [参照]を選ぶか、ソリューションエクスプローラーの中で、「参照」を右クリックして「参照の追加」を選ぶのが代表的方法です。

Visual Studio 2015くらいまではデフォルトではソリューションエクスプローラーには「参照」が表示されておらず、すべてファイルを表示することで、参照が表示されるようになります。

「すべてのファイルを表示」は下記画像の②のアイコンです。

(この画像は他から流用しているので、ここでは①と③には意味はありません。)

Visual Studio 2015でソリューションエクスプローラーにForm1.Designer.vbを表示する

 

参照マネージャーというウィンドウが開いて参照したいものを選択する画面になります。

Microsoft Docsに掲載されているフレームワークの機能は、アセンブリのフレームワークと拡張の一覧のどこかにあります。

※「フレームワーク」はフレームワーク本体、「拡張」は拡張機能というような意味のようですが、最近(2020年)は、この区別は難しいです。探しているアセンブリがフレームワークに見つからないようなら拡張から探してみてください。

Micorosft以外の第3者が作成したアセンブリを参照して呼び出すこともできます。「参照」ボタンをクリックすると自分でコンピューターの中から参照するファイルを探して指定することができます。アセンブリの拡張子は通常は dll か exe です。ただし、dllやexeの拡張子をもつファイルにはいろいろな種類があり、アセンブリでないものも多数あります。

 

.NET Coreの場合

.NET Coreの場合、NuGet(ヌゲット)という機能を使って、参照を追加します。

ソリューションエクスプローラーに「依存関係」という表示があるので、これを右クリックして、NuGet パッケージの管理 をクリックします。

参照をクリックして、検索欄に必要なアセンブリ名を入力して検索しましょう。

見つけたら、インストールをクリックして、確認事項にOK等押していけば完了です。

「インストール」という名前になっていますが、この操作で変更されるのはそのとき開いているVisual Studioのプロジェクトのみで、パソコンのアプリケーションとして何かがインストールされたりするわけではありません。

いろいろなファイルがダウンロードされますが、それらはすべてVisual Studioのプロジェクトが属しているソリューションのフォルダー内にダウンロードされます。

だから、NuGetでいろいろダウンロードして結局使わないのであれば、ソリューションフォルダーをまるごと削除すればよいし、ディスク容量の余裕があるのならば放置しておいても良いです。OSや環境には影響しません。

また、あるプロジェクトでNuGetでインストールした機能を、別のプロジェクトで使用したい場合は、もう1度そのプロジェクトでインストールする必要があります。

 

NuGetはインターネットを通して、必要なアセンブリをダウンロードします。NuGetはフレームワークのアセンブリ以外にも第3者が作成し、NuGetに登録したいろいろなアセンブリを導入することができるツールです。中にはMicrosoftが作成したものに匹敵するくらい人気のあるアセンブリもあります。NuGetを使うと他の人が使った便利な機能をあなたのアプリケーションに取り込んで呼び出すことができるようになります。ただし、ライセンス使用料が発生する場合もありますのでよくしらない機能をダウンロードするときはライセンスを確認しましょう。NuGetには他にも説明すべきことがあるので、別途どこかで取り上げると思います。

 

4-3.アセンブリが複数ある場合

Clipboardクラスの場合、アセンブリにSystem.Windows.Forms.dllと1つしか書かれていませんが、このアセンブリ欄に複数のアセンブリが記述されている場合があります。

たとえば、ZipFileクラスのアセンブリ欄には3つのdllファイルが記載されています。

これはフレームワークによってDLLが異なることを示しており、このうちどれか1つを参照すればZipFileクラスが使えるようになります。

この例の場合、

フレームワークが .NET Core ならば System.IO.Compression.ZipFile をNuGetで追加することでZipFileクラスが使えるようになります。

フレームワークが .NET Framework ならば、System.IO.Compression.FileSystem.dll に参照設定することでZipFileクラスが使えるようになります。

つまり、複数書いてあっても正解は1つだけです。Microsoft Docsのリファレンスのこの部分の記述は不親切で、この情報だけ見てもどれを参照すればよいのかわかりません。

.NET Coreの場合NuGetで、.NET Frameworkの場合参照設定で、探してみて見つけたものを使用してください。

発展 発展学習  -  netstandard.dll

発展学習では意欲的な方のために現段階では特に理解する必要はない項目を解説します。

最後に書いてあるnetstandard.dllはちょっと特殊で、.NET Coreとか.NET Frameworkなどのフレームワークの違いを意識しないでプログラムしたい場合に使用するものです。プロジェクトテンプレートの中で「クラスライブラリ (.NET Standard)」などを選択するとはじめからこれが参照されている状態でプログラムできます。このプロジェクトでルールどおりに作成すれば.NET Coreからも.NET Frameworkからも呼び出せる共通機能が作れるというわけです。

 

 

 

4-4.コンソールアプリケーションでClipboardクラスを呼び出す

ためしにコンソールアプリケーションで Clipboardクラスを呼び出せるようにしてみましょう。

コンソールアプリ(.NET Framework)を作成し、次のようにプログラムします。

名前空間を含めた完全修飾名でClipboardクラスを呼び出していますが、それでもエラーです。

そもそもClipboardクラスを含んでいるアセンブリが参照されていないからです。

Microsoft Docsによると、Clipboardクラスが含まれているアセンブリは System.Windows.Forms.dllです。

このアセンブリへの参照を追加しましょう。

そのために、ソリューションエクスプローラーで「参照」を右クリックして、「参照の追加」をクリックします。

※ソリューションエクスプローラーに「参照」が表示されていない場合は、ソリューションエクスプローラー上部にある「すべてのファイルを表示」をクリックすると表示されます。

「アセンブリ 」「フレームワーク」を選択して、一覧の中から System.Windows.Forms にチェックをつけ、OKをクリックします。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Module Module1

    Sub Main()
        System.Windows.Forms.Clipboard.SetText("ABC")
    End Sub

End Module

これで、さきほどのプログラムはエラーにならずに実行できるようになります。

実行すると、すぐに終了しますが、クリップボードに ABC をコピーしているので、メモ帳など何かに 貼り付け を行うと ABC が貼り付けられるのが確認できます。

 

ついでに、ファイルの先頭に Imports System.Windows.Forms と記述すると、このファイル内ではSystem.Windows.Forms名前空間の記述を省略できるようになるので、次のように簡単に Clipboard.SetTextメソッドの呼び出しをプログラムできるようにもなります。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Imports System.Windows.Forms

Module Module1

    Sub Main()
        Clipboard.SetText("ABC")
    End Sub

End Module

 

 

5.Importsによるクラスの指定

Importsには名前空間を省略可能にする機能のほかに、クラスや名前空間に別名を割り当てる機能があります。

たとえば、アプリケーションを起動するProcessクラスのStartメソッドは通常は次のように呼び出すことができます。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'電卓を起動します。
Process.Start("calc.exe")

名前空間を省略せずに完全修飾名を使用すると次のように呼び出すこともできます。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'電卓を起動します。
System.Diagnostics.Process.Start("calc.exe")

 

このProcessクラスに別名を与えるには、ファイルの先頭に次のように記述します。

この例では P という別名をつけていますので、プログラム内で Process と書く代わりに P と書くことができるようになります。

(Option StrictのようなOptionキーワードを使っている場合は、Option キーワードの方をファイルの先頭に書く必要があり、Importsはその後ろに記述します。)

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Option Strict On

Imports P = System.Diagnostics.Process

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        P.Start("calc.exe")

    End Sub
End Class

 

クラスではなく、名前空間に別名をつけることもできます。

次の例ではSystem.Diagnostics名前空間に diag という別名をつけているので、System.Diagnosticsと書く代わりに diag と書けるようになります。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Option Strict On

Imports diag = System.Diagnostics


Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        diag.Process.Start("calc.exe")

    End Sub
End Class

 

これらの別名はプログラムをわかりにくくするので使うべきではないと私は考えます。

Importsキーワードは初級講座 第5回 で説明したように 名前空間を省略できるようにする機能としてよく使いますが、別名をつける機能としてはお勧めしません。長いクラス名のクラスを使う場合など別名をつけたくなる場合があるかもしれませんが、Visual Studioの入力支援機能を使うほうが良いです。

 

6.Publicメンバーしか呼び出せません

Microsoft Docsのリファレンスを見るとたくさんのメンバーが並んでいますが、私たちが呼び出すことができるのはこのうち Public (読み方:Public = パブリック)なメンバーだけです。

たとえば、このButtonクラスのPerformClickメソッドは、Public で宣言されているので呼び出し可能です。

https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.button.performclick?view=netframework-4.8#System_Windows_Forms_Button_PerformClick

一方、次のControlクラスのOnClickメソッドは、Protected で宣言されているので、呼び出しできません。

https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.control.onclick?view=netframework-4.8#System_Windows_Forms_Control_OnClick_System_EventArgs_

PublicやProtectedの意味は、初級講座のもっと後の方で説明しますが、今のところは私たちが呼び出せるのは原則としてPublicなものだということを覚えておいてください。これは技術的には「スコープ」というトピックです。

発展 発展学習  -  スコープ

発展学習では意欲的な方のために現段階では特に理解する必要はない項目を解説します。

Publicで宣言されているものはどこからでも呼び出せます。

Privateで宣言されているものは同じクラス内からのみ呼び出せます。

Protectedで宣言されているものは同じクラス内または派生クラス内から呼び出せます。

Friendで宣言されているものは同じプロジェクト内から呼び出せます。

リフレクションを使うとPrivateやProtectedやFriendなどの区別なく呼び出せます。

この区別は、よく知らない人が呼び出してはいけないものを間違って呼び出せないようにする親切機能です。呼び出したくなるような機能をもっているメソッドやプロパティはだいたいPublicで宣言されているのでご安心ください。

 

 

博士のワンポイントレッスン 次回は練習回です。
V太 V太:いやー。前回と今回はなんかいろいろ難しいですね。重要そうなルールなんだと思うんですが、全部は覚えられないです。というか理解しきれないです。
B子 B子:特に今回ね。前回の原則論の方はなんとかわかった気がしたけど、今回は細かい話が多かったわね。
V太 博士:こういうのは、練習して身に付けていかんとなかなか自分のものにはならんなぁ。そこでじゃ、次回は練習の回として、前回と今回の知識を実践的に練習してみるつもりじゃ。
B子 いいですねー。楽しみ!
V太 ぼく、大丈夫かな・・・。