2012-02-08 14 views
3

C#アプリケーションでIronPythonをホストしています。 IronPhytonは、ユーザー用にDSLを実装するために使用されます。ホストされたアプリケーションで名前付き引数を使用して関数を呼び出す

Ping(Message = "testOne1") 

ホスティングコードは次のようになります:DSLの構文は次のようなものでなければなりません

var engine = Python.CreateEngine(); 
var scope = engine.CreateScope(); 

Action<string> ping = (message) => Console.WriteLine(message.ToString());    
scope.SetVariable("Ping", ping); 
var script = @" 
Ping(Message = ""testOne1"") 
"; 
engine.Execute(script, scope); 

しかしAction<string>は、引数の名前を保持していないので、これは動作しません。パラメータ名なしでそれを呼び出すには、期待通りに動作します:

Ping("testOne1") 

はどうやって機能を格納し、名前付き引数とそれを呼ぶのですか?

+0

代わりに名前に 'obj'を使用してみてください。これはデリゲート型の変数の名前です。 –

+0

'obj'はユーザーのDSLでうまく見えません:)。実際には引数の名前を指定する方法がない場合、 'Ping(" testOne1 ")'構文を使用するだけです。 –

答えて

4

を名前付き引数を使用するにはメソッドstatを定義する必要がありますically。たとえば、すべてのDSL操作を静的クラスOperationsに入れるだけです。そして、引数がうまくいくという名前

public static class Operations { 
    public static void Ping(string Message) { 
    Console.WriteLine(Message); 
    } 
} 

var engine = Python.CreateEngine(); 
var scope = engine.CreateScope(); 

// Load the assembly where the operations are defined. 
engine.Runtime.LoadAssembly(Assembly.GetExecutingAssembly()); 

// Import the operations modules, settings their names as desired. 
engine.Execute(@" 
from Operations import Ping 
", scope); 

// Now named arguments will work... 
var script = @" 
Ping(Message = ""Ping!"") 
"; 

engine.Execute(script, scope); 

今、私はあなたにいくつかの助言を与えることができれば、実際のPython APIをPythonで実装し、その呼び出しを必要に応じて.NETコードに戻したいと思っています。たとえば、代わりにC#で定義された「オペレーション」を有するのは、あなたのPythonのDSLを定義するOperations.pyファイルがあるだろう:

# Get access to your .NET API 
import clr 
clr.AddReference("MyAPI") 
import MyAPI 

# Define the Ping call to call into your .NET API 
def Ping(Message): 
    MyAPI.Ping(Message) 

をそして、あなたのホスティングコードは全く変更する必要はありません。

どちらも有効な解決策ですが、最後の方が簡単にDSLを繰り返し処理できます。

幸運を祈る!

+0

ありがとうございます。両方のソリューションが私のために働くでしょう。 –

0

パラメータの名前は、デリゲートタイプで指定された名前で定義されます。 Action<T>の場合、パラメータ名はobjです。

public delegate void Action<in T>(
    T obj 
) 

objが適しています。それは動作していないと確信していますか?わたしにはできる。

私は図書館持っているIronPythonのプロジェクトで

namespace TestLibrary 
{ 
    public static class Test 
    { 
     public static readonly Action<string> WriteLine = 
      msg => Console.WriteLine(msg); 

     // the same works if I do this instead 
     //public static readonly Action<string> WriteLine = Console.WriteLine; 
    } 
} 

をそして、この作品:

from TestLibrary import Test 

#Test.WriteLine(msg='foo') # error 
Test.WriteLine(obj='foo') # works 

主催、同契約:

var engine = Python.CreateEngine(); 
dynamic scope = engine.CreateScope(); 

Action<string> writeLine = msg => Console.WriteLine(msg); 
// or even 
//Action<string> writeLine = Console.WriteLine; 
scope.writeLine = writeLine; 

//engine.Execute("writeLine(msg='foo')", scope); // error 
engine.Execute("writeLine(obj='foo')", scope); // works 
+0

私は十分にはっきりしていないようです。しかし、「メッセージ」という名前は私が心配しているだけです。私の目標はまさに 'obj'や何か他のものではなく' Message'でした。 –

+0

とにかくお返事ありがとうございます。 –

+0

ああ、あなたはそれを 'メッセージ'にする必要がありました。ジミーの状態をメソッドとして定義することは、本当にあなたができる最良の方法です。これに慣れていれば、代わりに適切な名前を持つ新しいデリゲートを定義することができます。 –

関連する問題