简体   繁体   English

在托管应用程序中调用具有命名参数的函数

[英]Calling a function with named arguments in a hosted application

So I am hosting IronPython in my C# application. 所以我在我的C#应用​​程序中托管IronPython。 IronPhyton is used to implement a DSL for users. IronPhyton用于为用户实现DSL。 The DSL syntax should be something like this: DSL语法应该是这样的:

Ping(Message = "testOne1")

The hosting code looks like: 托管代码如下:

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);

But this does not work because Action<string> does not keep name of the argument. 但这不起作用,因为Action<string>不保留参数的名称。 Calling it without the parameter name works as expected: 在没有参数名称的情况下调用它可以按预期工作:

Ping("testOne1")

How do I store a function and call it with named arguments? 如何存储函数并使用命名参数调用它?

To use named arguments you'll have to define the method statically. 要使用命名参数,您必须静态定义方法。 For example, I'll just put all DSL operations into an Operations static class. 例如,我将把所有DSL操作都放入Operations静态类中。

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

Then named arguments will work: 那么命名参数将起作用:

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);

Now if I could give you some advise; 现在,如果我可以给你一些建议; I'd prefer to implement the actual Python API in Python, and have that call back into my .NET code as needed. 我更喜欢在Python中实现实际的Python API,并根据需要将其调用回我的.NET代码。 For example, instead of having the "operations" defined in C#, you'd have an Operations.py file which defines your Python DSL: 例如,您没有在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)

And your hosting code doesn't need to change at all. 您的托管代码根本不需要更改。

Both are valid solutions, but the last one lets you iterate on your DSL easily. 两者都是有效的解决方案,但最后一个可让您轻松地迭代DSL。

Good luck! 祝好运!

The name of the parameter is defined by the name provided in the delegate type. 参数的名称由委托类型中提供的名称定义。 In the case of Action<T> , the parameter name is obj . Action<T>的情况下,参数名称是obj

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

obj should work for you. obj应该适合你。 Are you sure it isn't working? 你确定它不起作用吗? It works for me. 这个对我有用。

In an IronPython project I have a library: 在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;
    }
}

And this works: 这有效:

from TestLibrary import Test

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

Hosted, same deal: 托管,同样的交易:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从.net程序调用托管的Filemaker应用程序 - calling a hosted Filemaker Application from a .net program 自托管wcf服务的调用函数 - Calling function of self hosted wcf service 如何使用Resharper自动对命名函数参数进行重新排序? - How to automatically reorder named function arguments with Resharper? VS/C# 调用方法时自动生成命名参数 - VS/C# Autogenerate Named Arguments when calling a method 使用两个参数调用WCF函数时出错 - Error when calling WCF function with two arguments 尝试从IIS中托管的Web应用程序连接到具有命名管道端点的WCF服务时,没有端点侦听错误 - No endpoint listening error when trying to connect to a WCF service with named pipe endpoint from Web application hosted in IIS 从同一IIS上托管的另一个Web应用程序调用Web应用程序是否有延迟? - Calling a web application from another web application hosted on the same IIS have latency? 使用C#Windows应用程序中的参数调用ClearCanvas exe - Calling ClearCanvas exe with arguments from c# windows application 确定 DLLImport 参数并安全地调用非托管 C 函数 - Determining DLLImport arguments and safely calling an unmanaged C function 有没有办法告诉在c#中调用函数的方法的参数? - Is there any way to tell the arguments of the method calling a function in c#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM