• ホーム
  • C#
  • C#でインスタンスをプログラムで作ってみた(Activator.CreateInstance編)

C#でインスタンスをプログラムで作ってみた(Activator.CreateInstance編)

C#で自前クラスのインスタンスを動的生成してみました。 試した環境は下記です。

  • Visual Studio 2015 for Windows Desktop

目次

  1. インスタンスの動的生成って?
  2. Activatorクラスを使ってみる
    1. 流れ
    2. Type.GetType()メソッド
    3. Activator.CreateInstance()メソッド
    4. Type.GetProperty()メソッド
    5. PropertyInfo.SetValue()メソッド
  3. 試してみた
    1. コード
    2. 動かしてみた

インスタンスの動的生成って?

コードを書いているときに必要なインスタンスがわかっていればnew演算子を使ってインスタンスを定義すれば良いです。でも、アプリケーションを実行している最中にインスタンスを追加したくなることがあります。 ということで、実行中にインスタンスを生成してみました。 何通りか方法があるようなのですが、総武ソフトウェア推進所のサイトの説明がとても参考になります。

Activatorクラスを使ってみる

Activatorクラスの説明をMSDNから引用します。

オブジェクトの型をローカル サイトまたはリモート サイトに作成するメソッド、または既存のリモート オブジェクトへの参照を取得するメソッドを保持します。

わからん。翻訳前の文章を引用してみます。

Contains methods to create types of objects locally or remotely, or obtain references to existing remote objects.

「いろいろなオブジェクトをローカルとかリモートに作ったり、リモートオブジェクトへの参照を取得するクラス」という感じでしょうか。今回はこのクラスのCreateInstanceメソッドを使います。

流れ

  1. 生成したいインスタンスの型をType型で取得する。

  2. 取得したType型を使って、Activator.CreateInstance()メソッドでインスタンスを生成する。

  3. 生成したインスタンスのプロパティを設定する。

Type.GetType()メソッド

Type.GetType()メソッドは、型をType型のオブジェクトとして取得するメソッドです。いくつかの構文があります。

Type type = Type.GetType(typeName); // typeNameが見つからない場合にはnullを返す。
Type type = Type.GetType(typeName, throwOnError); // typeNameが見つからない場合にはエラーを発生させる。

引数

内容

typeName

string

型を取得する名前。(生成するインスタンスのクラス名)

throwOnError

bool

型が見つからない場合にエラーを投げる場合はtrue、nullを返す場合はfalse。

戻り値は、Type型の型です。 他にも構文があるので、MSDNを参照してください。

Activator.CreateInstance()メソッド

CreateInstance()メソッドは、指定した型に基づいてインスタンスを生成するメソッドです。いくつかの構文があります。今回は一番単純なものを使います。

object instance = Activator.CreateInstance(type);

引数

内容

type

Type

生成するインスタンスの型

戻り値は、生成されたインスタンスへの参照です。

Type.GetProperty()メソッド

コードを書いているときには、ドット演算子でインスタンスのプロパティにアクセスできません。ですから、クラスのプロパティ情報を取得して、その情報を使って生成したインスタンスのプロパティに値を設定します。 Type.GetProperty()メソッドは、型の指定した名前のプロパティを検索するメソッドです。いくつか構文があります。今回使うのは単純なものです。

PropertyInfo property = Type.GetProperty(name);

引数

内容

name

string

プロパティ名。

戻り値は、PropertyInfoクラスのオブジェクトです。プロパティが見つからない場合にはnullが戻ります。

PropertyInfo.SetValue()メソッド

ドット演算子が使えませんので、プロパティ情報とインスタンスへの参照を使って、生成したインスタンスのプロパティに値を設定します。SetValue()メソッドにもいくつか構文がありますが、今回は単純なものを使います。

PropertyInfo.SetValue(instance, value)

引数

内容

instance

object

値を設定するインスタンスへの参照。

value

object

プロパティに設定する値。

戻り値はありません。

試してみた

インスタンスを動的生成して、プロパティに値を設定して、コンソールに出力するアプリを作ってみました。

コード

using System;
using System.Reflection;

namespace instance_trial
{
    class Program
    {
        static void Main(string[] args)
        {
            // コード作成時にインスタンスを定義する
            Tea preCreated = new Tea();
            preCreated.Name = "抹茶";

            Console.WriteLine(preCreated.Name);

            // 実行時にインスタンスを生成する
            Type typeOfClass = Type.GetType("instance_trial.Tea",true);  // クラスのTypeを取得する。
            object createdInstance = Activator.CreateInstance(typeOfClass);  // インスタンスを生成する。
            PropertyInfo propertyOfInstance = typeOfClass.GetProperty("Name");  // クラスのプロパティを取得する。
            propertyOfInstance.SetValue(createdInstance, "紅茶");  // インスタンスのプロパティに値を設定する。

            Console.WriteLine(propertyOfInstance.GetValue(createdInstance));
        }
    }

    class Tea
    {
        public string Name { get; set; }
    }
}

特に難しいことはしていないのですが、1つ引っかかりました。 Type.GetType()でクラスを指定する時に、namespace.クラス名というように名前空間を指定しないとエラーになりました。「同じ名前空間のクラスなんだから指定しなくても良くない?」と思うのですが、ダメでした。

動かしてみた

下図の様に、動的生成したインスタンスのプロパティの値も表示されました。 160419-1-01

公開日

広告