3

私は小さなスクリプト言語を継承しており、管理が少し簡単になるようにDLRに移植しようとしています。これまでのところ、それはかなり簡単です。変数のメンバーを動的に呼び出そうとしましたが、問題が発生しました。現在の言語は.NETで実行され、解析ループとリフレクションを使用してこれを実行しますが、私はそれから逃れることを望んでいました。スクリプト言語の例を次に示します。

string $system1RemoteUri;
string $dbconnection = $config.GetDBConnection ("somedb");
float $minBad = 0.998;
float $minGood = 0.2;

$ systen1RemoteURI、$ minBad、および$ minGoodは、$dbconnectionとともにスクリプトで設定される変数です。ただし、$ dbconnectionは、$configと呼ばれる渡された変数からその値を取得します。4つの変数は呼び出し元が使用できる必要があるため、最初はnullとしてラムダに渡されます。生成されたLambdaIL(デバッグビュー)は次のとおりです。

.Lambda #Lambda1<Delegate6$1>(
    System.String& $$system1RemoteUri,
    System.String& $$dbconnection,
    System.Double& $$minBad,
    System.Double& $$minGood
    System.Object $$config) {
    .Block() {
        $$minBad = 0.998D;
        $$minGood = 0.2D
    }

    //Some assignment similar to...
    //.Dynamic Call GetDBConnection($config, "somedb");
}

私が理解しようとしているのは、Expression.Dynamicを使用して$ config.GetDBConnection( "somedb")を発行する方法です。Symplライブラリの例を見ると、発行されるILは次のようになります。.DynamicCall GetdbConnection($ config、 "somedb")ですが、Expression.Dynamicから実際に発行する方法がわかりません。

正しく作成できないCallSiteBinderが必要なようです。また、ベースではなく「メンバー」のみが呼び出されるように見えるため、Expression.Dynamicのパラメーターの順序がわかりません。

$ configのランタイムタイプはわかりません。これは、GetDBConnection(string)という関数を実装するオブジェクトにすぎません。これは、インターフェースまたは基本クラスによって提供されません。

どんな助けでもいただければ幸いです。

4

1 に答える 1

4

これをInvokeMemberBinderに変換するか、「$ config.GetDBConnection」をGetMemberに変換してから、引数として$someDbを渡した結果に対してInvokeを実行できます。

GetMemberBinderとInvokeMemberBinderを実装するには、DLR外部レイヤーのDefaultBinderクラスを使用できます。最新のIronPython/IronRubyソースコードでは、空中から新しいDefaultBinderインスタンスを作成できます。次に、FallbackGetMember / FallbackInvokeで、defaultBinder.GetMember(...)およびdefaultBinder.Call(名前をInvokeに変更する必要があります)を呼び出すことができます。これで、ほとんどの.NETタイプを処理できます。また、IDynamicMetaObjectProviderを実装するすべてのオブジェクトも同様に機能します。他の動的操作については、デフォルトのバインダーで他のメソッドを使用できます。また、オーバーロードの解決とバインディングルールのカスタマイズを開始したい場合は、回すことができるノブがたくさんあります。

残念ながら、デフォルトのバインダーには現在InvokeMemberBinderの実装がないため、GetMember/Invokeを使用した方がよいでしょう。

于 2010-01-26T07:10:08.033 に答える