読者です 読者をやめる 読者になる 読者になる

いろいろ備忘録日記

主に .NET と Python絡みのメモを公開しています。

.NET クラスライブラリ探訪-001 (System.Activator)

.NETフレームワークには、非常に多くのクラスがあります。
(Javaと同じくらい、下手するともっと多いかも・・・・)


いっぱいあるのは便利なんですが、これだけ多いと全体を知るのは
ほぼ不可能でしょう。てことで、目についたクラスをとりあえず
試してみていった結果をメモ程度に書いていければな〜と思ってます。


最初のクラスは、System.Activator。


このクラスは、オブジェクトの作成を担当しています。
文字列からオブジェクトを作成したり、特定のSystem.Typeオブジェクトから
オブジェクトを作成したり、さらに特定のアセンブリからオブジェクトを作成
したりなどです。ドキュメントを見るとCOMオブジェクトも作成できるみたいです。
リフレクションでは必須の機能ですね。


以下、サンプルです。


なお、対象としているのは.NET 2.0のクラスライブラリです。

// vim:set ts=4 sw=4 et ws is nowrap ft=cs:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Remoting;

using Gsf.Research.ClassLibrary;

namespace Gsf.Research.ClassLibrary.System{

    /// <summary>
    /// System.Activatorクラスの使用サンプルです。
    /// </summary>
    /// <remarks>
    /// System.Activatorに対しての簡単な使用サンプルです。
    /// CreateInstanceメソッドを利用して動的にインスタンスを作成します。
    /// </remarks>
    /// <seealso cref="System.Activator" />
    public class ActivatorResearch00 : IExecutable{

        /// <summary>
        /// 処理を実行します。
        /// </summary>
        public void Execute(){
            //
            // System.Collections.ArrayListオブジェクトを動的に作成.
            // コールされるのは、引数の無いバージョンのコンストラクタとなる.
            //
            object o = Activator.CreateInstance(Type.GetType("System.Collections.ArrayList"));

            ArrayList al = o as ArrayList;
            al.AddRange(new object[]{"hoge", "hehe"});
            foreach(object v in al){
                Console.WriteLine(v);
            }

            //
            // ジェネリック型であるSystem.Collection.Generic.Listオブジェクトを動的に作成.
            // 型引数は、stringとする。
            //
            // [補足]
            // Type.GetTypeにて、ジェネリックな型を生成するには以下のような書式で行う.
            //
            //      型名`型引数の個数[型引数の型......(複数の場合はカンマで区切る)]
            //
            // たとえば、型引数を2つとるDictionaryの場合は、
            //
            //      System.Collections.Generic.Dictionary`2[System.String, System.Type]
            //
            // のようになる。
            // また、これは以下の場合と同じとなる。
            //
            //      typeof(Dictionary<string, Type>)
            //
            Type t = Type.GetType("System.Collections.Generic.List`1[System.String]");
            
            List<string> li = Activator.CreateInstance(t) as List<string>;
            li.AddRange(new string[]{"hoge", "hehe"});
            li.ForEach(delegate(string v){
                Console.WriteLine(v);
            });

            //
            // 特定のアセンブリから動的にオブジェクトを作成する.
            // 
            // 以下のサンプルでは、Firebirdのデータプロバイダーライブラリからオブジェクトを見つけるようにしてみる。
            //
            // Activator.CreateInstance(string, string)で返却されるのは、System.Runtime.Remoting.ObjectHandleという
            // クラスのオブジェクト。このオブジェクトは、内部に参照先のオブジェクトをラップして保持している。
            // Unwrapメソッドで、実際のオブジェクトを取得できる.
            //
            Assembly     asm    = Assembly.LoadFrom(@"/MyLib/FirebirdSql.Data.FirebirdClient.dll");
            ObjectHandle handle = Activator.CreateInstance(asm.FullName, "FirebirdSql.Data.FirebirdClient.FbConnection");
            Console.WriteLine(handle.Unwrap().GetType().FullName);
        }
    }
}

================================
過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。