.NET TIPS

文字列で指定したクラスのインスタンスを作成するには?

デジタルアドバンテージ 遠藤 孝信
2005/12/09

 通常、クラスのインスタンスは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
クラス名からインスタンスを作成するC#のサンプル・プログラム(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
クラス名からインスタンスを作成するVB.NETのサンプル・プログラム(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
アセンブリをロードしてクラス名からインスタンスを作成するC#のサンプル・プログラム(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
アセンブリをロードしてクラス名からインスタンスを作成するVB.NETのサンプル・プログラム(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
C#によるjedi.dllのソース・コード(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
VB.NETによるjedi.dllのソース・コード(jedi.vb)

 上記のmain.cs(main.vb)中にコメントで示したように、AssemblyクラスにもCreateInstanceメソッドが用意されており、このメソッドを利用すればTypeオブジェクトの作成部分をショートカットできる。End of Article

カテゴリ:クラス・ライブラリ 処理対象:リフレクション
使用ライブラリ:Typeクラス(System名前空間)
使用ライブラリ:Activatorクラス(System名前空間)
使用ライブラリ:Assemblyクラス(System.Reflection名前空間)

この記事と関連性の高い別の.NET TIPS
プログラムからソース・コードをコンパイルして実行するには?
文字列で指定したメソッドを呼び出すには?
クラス名指定のインスタンス作成時にコンストラクタへ引数を渡すには?
実行ファイルのパスを取得するには?
コントロールのクラス名からコントロール・オブジェクトを作成するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」

TechTargetジャパン

Insider.NET フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

キャリアアップ


- PR -

イベントカレンダー

PickUpイベント

- PR -

アクセスランキング

もっと見る
- PR -

ホワイトペーパーTechTargetジャパン

ソリューションFLASH

「ITmedia マーケティング」新着記事

第1回 BtoBマーケティングの実践における「可視化」の目的と設計方法
BtoBマーケティングにおける「可視化」とは、顧客企業の購買プロセスを明らかにすること...

第2回 技術の進化がマーケティングに与えたインパクト
第2回では、新しいKKD(「仮説」「検証」「データ分析」)が意味を持つようになった時代...

第5回 Webサイトの目的を社内で共有する――他部署をうまく巻き込むには?
遠藤さんのプレゼンがいよいよ始まる。Webサイトのリニューアルプランに「ソーシャルメデ...