2012-02-08 3 views
3

Итак, я принимаю IronPython в своем приложении C#. IronPhyton используется для реализации DSL для пользователей. Синтаксис DSL должен быть чем-то вроде этого:Вызов функции с именованными аргументами в размещенном приложении

Ping(Message = "testOne1") 

хостинг код выглядит следующим образом:

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 чески. Например, я просто поставлю все операции 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#, вы бы иметь Operations.py файл, который определяет ваш Python DSL:

# 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

Кажется, я был недостаточно ясен. Но имя 'Сообщение' есть только забота, которую я имею. Моя цель была именно 'Message' не' obj' или что-то еще. –

+0

Спасибо вам за ответ в любом случае. –

+0

О, так что вы _needed_ это было 'Message'. Определение метода как состояния Джимми - действительно лучшее, что вы можете сделать.Хотя, если вы открыты для этого, вы можете определить новый делегат с соответствующими именами в качестве альтернативы. –

 Смежные вопросы

  • Нет связанных вопросов^_^