C#でインスタンスをプログラムで作ってみた(Activator.CreateInstance編)
C#で自前クラスのインスタンスを動的生成してみました。 試した環境は下記です。
Visual Studio 2015 for Windows Desktop
目次
インスタンスの動的生成って?
コードを書いているときに必要なインスタンスがわかっていればnew演算子を使ってインスタンスを定義すれば良いです。でも、アプリケーションを実行している最中にインスタンスを追加したくなることがあります。 ということで、実行中にインスタンスを生成してみました。 何通りか方法があるようなのですが、総武ソフトウェア推進所のサイトの説明がとても参考になります。
Activatorクラスを使ってみる
Activatorクラスの説明をMSDNから引用します。
オブジェクトの型をローカル サイトまたはリモート サイトに作成するメソッド、または既存のリモート オブジェクトへの参照を取得するメソッドを保持します。
わからん。翻訳前の文章を引用してみます。
Contains methods to create types of objects locally or remotely, or obtain references to existing remote objects.
「いろいろなオブジェクトをローカルとかリモートに作ったり、リモートオブジェクトへの参照を取得するクラス」という感じでしょうか。今回はこのクラスのCreateInstanceメソッドを使います。
流れ
生成したいインスタンスの型をType型で取得する。
取得したType型を使って、Activator.CreateInstance()メソッドでインスタンスを生成する。
生成したインスタンスのプロパティを設定する。
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.クラス名というように名前空間を指定しないとエラーになりました。「同じ名前空間のクラスなんだから指定しなくても良くない?」と思うのですが、ダメでした。
公開日
広告
C#カテゴリの投稿
- C#でMVVMって何でしょう
- C#でPDFを表示する(WPF)
- C#でアプリのログを記録してみる
- C#でアプリの設定を保存する
- C#でインスタンスをプログラムで作ってみた(Activator.CreateInstance編)
- C#でインスタンスをプログラムで作ってみた(Type.InvokeMember編)
- C#でインスタンス間のデータの受け渡しをしてみた
- C#でウェブサイトのソースを取得してみた
- C#でエラーの処理をする
- C#でクラスのフィールド宣言とコンストラクターでの初期化はどっちが優先する?
- C#でスタックを使って逆ポーランド記法の計算をしてみた
- C#で数式を中置記法から後置記法(逆ポーランド記法)に変換してみた(三角関数編)
- C#で選択(switch-case編)
- C#のWPFでデータバインディング
- C#のXAMLでメニューとステータスバーのレイアウトをしてみた
- C#のアプリの情報を表示してみた
- C#のクラスとインスタンスとオブジェクト
- C#の反復処理(foreach編)
- C#の命名規則
- C#へのMicrosoft.TeamFoundation.Controlsの参照の追加について