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

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

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

  • Visual Studio 2015 for Windows Desktop

目次

  1. インスタンスの動的生成って?
  2. Type.InvokeMember()メソッドを使ってみる
    1. 流れ
    2. typeof()演算子
    3. Type.InvokeMember()メソッド
  3. 試してみた
    1. コード
    2. 動かしてみた

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

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

Type.InvokeMember()メソッドを使ってみる

Type.InvokeMember()メソッドは、Typeのメンバーを呼び出すものです。つまり、クラスからType型のオブジェクトを作って、そのオブジェクトのメンバーであるコンストラクターを呼び出すことで、インスタンスを作ったりします。

流れ

  1. 生成したいインスタンスの型をType型オブジェクトで取得する。

  2. 取得したType型オブジェクトのInvokeMember()メソッドでインスタンスを生成する。

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

typeof()演算子

Type.GetType()メソッドを使うとクラスからType型オブジェクトを作れます。同様にtypeof()演算子を使って、クラスからType型オブジェクトを作れます。

Type type = typeof(typeName);

引数

内容

typeName

class

Typeオブジェクトを取得する型

戻り値はType型のオブジェクトです。

Type.InvokeMember()メソッド

Type.InvokeMember()メソッドには、いくつか構文があります。今回は一番単純なものを使います。

インスタンス生成

object instance = Type.InvokeMaker(null, BindingFlags.CreateInstance, null, null, args)

引数

内容

args

object[]

呼び出すメンバーに渡す引数の配列

戻り値はインスタンスを表すオブジェクトです。

プロパティに値設定

Type.InvokeMaker(name, BindingFlags.SetProperty, null, target, args)

引数

内容

name

string

値を設定するプロパティ名

target

object

変更対象となるインスタンス名

args

object[]

プロパティに格納する値

プロパティから値取得

object obj = Type.InvokeMaker(name, BindingFlags.GetProperty, null, target, null)

引数

内容

name

string

値を取得するプロパティ名

target

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を取得する。 (GetTypeメソッド版)
            Type typeOfClass = typeof(Tea);  // クラスのTypeを取得する。(typeof演算子版)
            object createdInstance = typeOfClass.InvokeMember(null, BindingFlags.CreateInstance, null, null, null);  //  インスタンスを生成する。
            typeOfClass.InvokeMember("Name", BindingFlags.SetProperty, null, createdInstance, new object[] { "烏龍茶" });  // プロパティに値を設定する。

            object propertyValue = typeOfClass.InvokeMember("Name", BindingFlags.GetProperty, null, createdInstance, null);  // プロパティの値を取得する。
            Console.WriteLine(propertyValue.ToString());
        }
    }

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

動かしてみた

下図の様に、動的生成したインスタンスのプロパティの値も表示されました。 160419-3-01 自前クラスにコンストラクターを設定していませんが、InvokeMemberで呼べるのですね。

公開日

広告