Как выставить перегруженные методы встроенному интерпретатору IronPython? - PullRequest
2 голосов
/ 06 апреля 2010

Я встроил движок IronPython в приложение C #. Я хочу представить некоторые пользовательские команды (методы) для интерпретатора. Как мне это сделать?

В настоящее время у меня есть что-то вроде этого:

public delegate void MyMethodDel(string printText);

Main(string[] args)
{
    ScriptEngine engine = Python.CreateEngine();
    ScriptScope scope = engine.CreateScope();

    MyMethodDel del = new MyMethodDel(MyPrintMethod);
    scope.SetVariable("myprintcommand", del);

    while(true)
    {
        Console.Write(">>>");
        string line = Console.ReadLine();

        ScriptSource script = engine.CreateScriptSourceFromString(line, SourceCodeKind.SingleStatement);
        CompiledCode code = script.Compile();
        script.Execute(scope);
    }
}

void MyPrintMethod(string text)
{
    Console.WriteLine(text);
}

Я могу использовать это так:

>>>myprintcommand("Hello World!")
Hello World!
>>>

Это отлично работает. Я хотел знать, является ли это правильным способом / наилучшей практикой делать то, чего я хочу достичь?

Как я могу выставить перегрузки того же метода. Например, если я хотел предоставить такой метод, как myprintcommand (строковый формат, object [] args).

При том способе, которым я сейчас занимаюсь, ключ "myprintcommand" может быть сопоставлен только одному делегату. Поэтому мне придется изменить имя команды / метода, если я хочу показать перегруженную «myprintcommand» интерпретатору. Есть ли другой способ добиться того, чего я хочу?

Ответы [ 2 ]

2 голосов
/ 06 апреля 2010

Вам, вероятно, придется написать свою собственную логику для этого. Например:

public delegate void MyMethodDel(params object[] args);

void MyPrintMethod(params object[] args)
{
  switch (args.Length)
  {
    case 1:
      Console.WriteLine((string)args[0]);
      break;
    ...
    default:
      throw new InvalidArgumentCountException();
  }
}

Это может или не может работать; Я не уверен, как они обрабатывают атрибут «params».

1 голос
/ 06 апреля 2010

Есть более простой способ сделать это. Вместо того чтобы использовать область действия скрипта, чтобы сделать член доступным для IronPython, вы можете загрузить сборку C # в среду выполнения движка.

engine.Runtime.LoadAssembly(typeof(MyClass).Assembly);

Это позволит предварительно загрузить сборку, содержащую класс MyClass. Например, предполагая, что MyPrintMethod является статическим членом MyClass, вы сможете выполнить следующий вызов из интерпретатора IronPython.

from MyNamespace import MyClass
MyClass.MyPrintMethod('some text to print')
MyClass.MyPrintMethod('some text to print to overloaded method which takes a bool flag', True)
...