DLRにおけるオブジェクト・メンバーリストの取得方法

Silverlight 2.0 Beta1 SDKに含まれているDLRは、IronPython 2.0A8相当です。IronPython 2.0 Beta1に含まれるDLR相当を使いたい場合は、Dynamicsilverlight.netのFlickrサンプルから試してください。今回は、DLRを使ったオブジェクトのメンバーを言語非依存で参照する方法をご紹介します。例えば、以下のPythonコマンドを見てください。

 >>> import datetime
>>> dir(datetime)
['MAXYEAR', 'MINYEAR', '__builtins__', '__name__', 'date',
 'datetime', 'time', 'timedelta', 'tzinfo']

pythonのdir関数でdatetimeモジュールに含まれるメンバーを表示しています。これと同じことを行うのが、以下のコードです。

 ScriptDomainManager sdm;
IScriptEngine engine;
IScriptScope scope;
string import = "import datetime"
sdm = ScriptDomainManager.CurrentManager;
engine = sdm.GetEngine("py");
// import datetimeを実行する
SourceUnit su = engine.CreateScriptSourceFromString(
               import, SourceCodeKind.Statements);
scope = engine.CreateScope();
engine.Execute(scope, su);
// datetimeモジュールを取得する
object datetime_object;
bool bret = eng.TryGetVariable(scope, 
               "datetime", out datetime_object);
// datetimeモジュールのメンバーを取得する
IList<string> mls = engine.Operations.
                 GetMemberNames(datetime_object);

これでmlsにメンバーリストが返ってきます。このコードのポイントは、TryGetVariableメソッドでオブジェクトを取得してから、Operations.GetMemberNamaesメソッドでメンバーリストを取得することです。注意しないといけないのは、GetMemberNamaesメソッドが例外を出力する可能性があることです。
では、次のpythonコードを見てください。

 >>> dir(datetime.date)
['CheckType', 'CompareTo', 'Equals', 'GetHashCode', 'InternalDateTime', 'ToStrin
g', '__add__', '__class__', '__delattr__', '__doc__', 
'__eq__', '__ge__', '__getattribute__', '__getnewargs__', 
長いので省略しています
 'strftime', 'timetuple', 'today', 'toordinal', 'weekday', 'year']

datetimeモジュールのdateクラスのメンバーをdir関数で取得しています。これと同じことをDLRで行うのが、以下のコードになります。

 // dateクラスの型を取得する
object p_date;
ret = engine.Operations.TryGetMember(
             datetime_object, "date", out p_date);
// dateクラスのメンバを取得する
var wk = engine.Operations.DoOperation(
                       Operators.MemberNames, p_date);
IList<string> dmls = SymbolTable.IdsToStrings(
                       (IList<SymbolId>) wk);

これでdmlsにdateクラスのメンバーリストが返ってきます。このコードのポイントは、Operations.TryGetMemberメソッドでdatetimeモジュールのdateクラスの型を取得することと、Operations.DoOperationメソッドでしょう。DoOperationメソッドを使うことで、変数として管理されていないクラス(型)のメンバーを取得しています。この結果は、SymbolIdのListコレクションとして返ってきますので、SymbolTable.IdsToStringメソッドで、文字列のListに変換しています。

このようにすることで言語非依存でオブジェクトのメンバーを取得することができるようになります。これらの機能を組み合わせたのが、DLR Consoleのインテリセンスなのです。
IDE支援というか開発支援のインフラとしてのコード補完機能として、このような機能がDLRには用意されています。