この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
通常、クラスのインスタンスはnewキーワード(VB.NETの場合はNewキーワード)により作成するが、リフレクションの機能により、文字列で指定されたクラス名からインスタンスを作成することもできる。
本稿では、インスタンス化したいクラスを含んだアセンブリがすでにロードされている場合と、そのアセンブリがまだロードされていない場合の2つのケースについて、クラス名からインスタンスを作成する方法について解説する。
インスタンス化したいクラスを含んだアセンブリがすでにディスクからロードされている場合には、まずTypeクラス(System名前空間)のGetTypeメソッドにより、そのクラスのTypeオブジェクトを得る。GetTypeメソッドでは、パラメータとしてクラス名を文字列で指定できる。
Type t = Type.GetType("インスタンス化したいクラス名");
Typeオブジェクトは、特定のクラス(型)に関する情報を含んだオブジェクトである。Typeオブジェクトが得られれば、Activatorクラス(System名前空間)のCreateInstanceメソッドにより、そのTypeオブジェクトが示すクラスのインスタンスを作成できる。
object o = Activator.CreateInstance(t);
このCreateInstanceメソッドは作成したインスタンスをobject型として返すため、そのインスタンスのメンバにアクセスするには何らかのキャストが必要となる。
以下にこれら2つのメソッドを利用した例を示す。
// createinstance.cs
using System;
public class MasterClass {
public virtual void Say() {
Console.WriteLine("Use the Force");
}
}
public class PadawanClass : MasterClass {
public override void Say() {
Console.WriteLine("Yes, Master");
}
}
public class JediMaster {
static void Main() {
Type masterType = Type.GetType("MasterClass");
MasterClass obiwan
= (MasterClass)Activator.CreateInstance(masterType);
obiwan.Say(); // 出力:Use the Force
Type padawanType = Type.GetType("PadawanClass");
MasterClass anakin
= (MasterClass)Activator.CreateInstance(padawanType);
anakin.Say(); // 出力:Yes, Master
}
}
// コンパイル方法:csc createinstance.cs
' createinstance.vb
Imports System
Public Class MasterClass
Public Overridable Sub Say()
Console.WriteLine("Use the Force")
End Sub
End Class
Public Class PadawanClass
Inherits MasterClass
Public Overrides Sub Say()
Console.WriteLine("Yes, Master")
End Sub
End Class
Public Class JediMaster
Shared Sub Main()
Dim masterType As Type = Type.GetType("MasterClass")
Dim obiwan As MasterClass = _
CType(Activator.CreateInstance(masterType), MasterClass)
obiwan.Say() ' 出力:Use the Force
Dim padawanType As Type = Type.GetType("PadawanClass")
Dim anakin As MasterClass = _
CType(Activator.CreateInstance(padawanType), MasterClass)
anakin.Say() ' 出力:Yes, Master
End Sub
End Class
' コンパイル方法:vbc createinstance.vb
このサンプル・プログラムには、インスタンス化したいクラス(MasterClassクラスやPadawanClassクラス)とインスタンス化のためのコードの両方が含まれているため、GetTypeメソッドをいきなり呼び出して、それらのクラスのTypeオブジェクトが取得可能である。
アセンブリがまだロードされていない場合には、まずそのアセンブリを明示的にロードしてやる必要がある。これにはAssemblyクラス(System.Reflection名前空間)のLoadFromメソッドが使える。パラメータには、ロードしたいアセンブリを含むファイル(通常はDLLファイル)のパス名を指定する。
Assembly asm = Assembly.LoadFrom("アセンブリのファイル名");
Assemblyオブジェクトは、特定のアセンブリに関する情報を含んだオブジェクトである。このAssemblyクラスにも、Typeクラスと同様にGetTypeメソッドが用意されており、クラス名により、そのアセンブリに含まれるクラスのTypeオブジェクトを作成できる。
Type t = asm.GetType("インスタンス化したいクラス名");
Typeオブジェクトを取得できれば、あとは先ほどと同様にActivator.CreateInstanceメソッドによりインスタンス化が可能だ。以下にその例を示す。
なお以下のプログラムでは、MasterClassクラスとPadawanClassクラスが「jedi.dll」というDLLファイル(後掲)に含まれているものとする。コンパイル時にはjedi.dllを参照する必要がある。
// main.cs
using System;
using System.Reflection;
public class JediMaster {
static void Main() {
Assembly asm = Assembly.LoadFrom("jedi.dll");
Type masterType = asm.GetType("MasterClass");
MasterClass obiwan
= (MasterClass)Activator.CreateInstance(masterType);
// 上の3行は次のようにも記述可能
// MasterClass obiwan
// = (MasterClass)asm.CreateInstance("MasterClass");
obiwan.Say(); // 出力:Use the Force
Type padawanType = asm.GetType("PadawanClass");
MasterClass anakin
= (MasterClass)Activator.CreateInstance(padawanType);
// 上の3行は次のようにも記述可能
// MasterClass anakin
// = (MasterClass)asm.CreateInstance("PadawanClass");
anakin.Say(); // 出力:Yes, Master
}
}
// コンパイル方法:csc /r:jedi.dll main.cs
' main.cs
Imports System
Imports System.Reflection
Public Class JediMaster
Shared Sub Main()
Dim asm As [Assembly] = [Assembly].LoadFrom("jedi.dll")
Dim masterType As Type = asm.GetType("MasterClass")
Dim obiwan As MasterClass = _
CType(Activator.CreateInstance(masterType), MasterClass)
' 上の3行は次のようにも記述可能
' Dim obiwan As MasterClass = _
' CType(asm.CreateInstance("MasterClass"), MasterClass)
obiwan.Say() ' 出力:Use the Force
Dim padawanType As Type = asm.GetType("PadawanClass")
Dim anakin As MasterClass = _
CType(Activator.CreateInstance(padawanType), MasterClass)
' 上の3行は次のようにも記述可能
' Dim anakin As MasterClass = _
' CType(asm.CreateInstance("PadawanClass"), MasterClass)
anakin.Say() ' 出力:Yes, Master
End Sub
End Class
' コンパイル方法:vbc /r:jedi.dll main.vb
続いてjedi.dllのソース・コードを示す。
// jedi.cs
using System;
public class MasterClass {
public virtual void Say() {
Console.WriteLine("Use the Force");
}
}
public class PadawanClass : MasterClass {
public override void Say() {
Console.WriteLine("Yes, Master");
}
}
// コンパイル方法:csc /t:libarary jedi.cs
' jedi.vb
Imports System
Public Class MasterClass
Public Overridable Sub Say()
Console.WriteLine("Use the Force")
End Sub
End Class
Public Class PadawanClass
Inherits MasterClass
Public Overrides Sub Say()
Console.WriteLine("Yes, Master")
End Sub
End Class
' コンパイル方法:vbc /t:library jedi.vb
上記のmain.cs(main.vb)中にコメントで示したように、AssemblyクラスにもCreateInstanceメソッドが用意されており、このメソッドを利用すればTypeオブジェクトの作成部分をショートカットできる。
カテゴリ:クラス・ライブラリ 処理対象:リフレクション
使用ライブラリ:Typeクラス(System名前空間)
使用ライブラリ:Activatorクラス(System名前空間)
使用ライブラリ:Assemblyクラス(System.Reflection名前空間)
Copyright© Digital Advantage Corp. All Rights Reserved.