[C#][dynamic] 列挙型 (enum) の列挙子の動的な取得など
今回は、列挙型 (enum) の列挙子の取得などについて。
■ 列挙型 (enum) の列挙子を動的なメソッド呼び出しの引数で渡したい
例えば、次のようなクラス ライブラリー (ClassLibrary.dll) があるとする。
// クラス ライブラリー側: ClassLibrary.dll namespace ClassLibrary { // 列挙型 (enum) public enum ItemKind { Book, Toy, Stationary } // クラス public class Item { // アイテムの種類 (型は列挙型の ItemKind) readonly ItemKind itemType; // コンストラクター (引数でアイテムの種類を指定) public Item(ItemKind itemType) { this.itemType = itemType; } } }
そして、別のプロジェクトで、このクラス ライブラリーを動的に読み込んで使いたいとする。
例.
// クラス ライブラリーを動的に利用する側: Xxx.exe using System; using System.Reflection; class Program { static void Main() { // アセンブリ名を使ってクラス ライブラリーを動的に読み込み var assembly = Assembly.Load("ClassLibrary"); // アセンブリ内のクラスの型情報を取得 var itemType = assembly.GetType("ClassLibrary.Item"); // ... 途中省略 ... } }
ここで次のように、型情報 itemType を使って、インスタンスを生成させようとしてみる。
// ... 途中省略 ... // アセンブリ名を使ってクラス ライブラリーを動的に読み込み var assembly = Assembly.Load("ClassLibrary"); // アセンブリ内のクラスの型情報を取得 var itemType = assembly.GetType("ClassLibrary.Item"); // クラスの型情報を使って、クラスのインスタンスを生成 dynamic item = Activator.CreateInstance(itemType, 0 /* ClassLibrary.ItemKind.Book の値 */); // ... 途中省略 ...
これは次のように、実行時エラーになる。
コンストラクターの引数の型が合っていないからだ。
勿論、object にキャストしても実行時エラーの儘だ。
だが、クラス ライブラリーを動的に読み込みたい訳なので、ClassLibrary.ItemKind.Book と書く訳にもいかない。
// ... 途中省略 ... // クラスの型情報を使って、クラスのインスタンスを生成 dynamic item = Activator.CreateInstance(itemType, ClassLibrary.ItemKind.Book); // コンパイル エラー // ... 途中省略 ...
こういう場合はどうすれば良いだろうか?
これは、次のように、列挙型 (enum) の型情報も取得して、そこから ClassLibrary.ItemKind.Book を生成してやれば良い。
// ... 途中省略 ... // アセンブリ内の列挙型 (enum) の型情報をアセンブリから取得 var itemKindType = assembly.GetType("ClassLibrary.ItemKind"); // enum の列挙オブジェクト ClassLibrary.ItemKind.Book を生成 var itemKindTypeBook = Enum.Parse(itemKindType, "Book"); // クラスの型情報を使って、クラスのインスタンスを生成 dynamic item = Activator.CreateInstance(itemType, itemKindTypeBook); // ... 途中省略 ...
Enum.Parse メソッドを使って enum の列挙子名から列挙オブジェクトを生成するのがポイントだ。
■ 列挙型 (enum) の列挙子の名称を取得
列挙型 (enum) の型情報から全ての列挙子の名称を取得することもできる。
例えば、列挙型 (enum) ClassLibrary.ItemKind の全ての列挙子の名称を取得するには次のようにすれば良い。
// ... 途中省略 ... // 列挙型 (enum) の全ての列挙子の名称を取得 string[] itemKindTypeNames = Enum.GetNames(typeof(ClassLibrary.ItemKind)); // ... 途中省略 ...
列挙子の名称が配列で得られる。即ち、ここから列挙子の数を取得することができることになる。
// ... 途中省略 ... // 列挙型 (enum) の列挙子の数を取得 int itemKindTypeLength = Enum.GetNames(typeof(ClassLibrary.ItemKind)).Length; // ... 途中省略 ...
Enum.GetTypes メソッドで、全ての列挙子オブジェクトを配列 (Array) で取得することもできるので、次のようにしても良い。
// ... 途中省略 ... // 列挙型 (enum) の列挙子の数を取得 int itemKindTypeLength = Enum.GetTypes(typeof(ClassLibrary.ItemKind)).Length; // ... 途中省略 ...
ディスカッション
コメント一覧
まだ、コメントがありません