2

My goal is to convert a Python function to a function in C# with the same functionality. The important aspect here is that I have information in Python on the input types and output types of the function. This information should be transferred to the function in C#.

Using IronPython I can integrate the Python function to C# with object as input and output types. Currently I have the following code:

    class Program 
    {
        public static void Main(string[] args) {
        var engine = Python.CreateEngine();
        var scope = engine.CreateScope();
        var source = engine.CreateScriptSourceFromString(
                "def Add(arg1, arg2):\n" +
                "   return arg1 +1\n"  +
                "\n" +
                "functionTypes = int" +
                "\n" +
                "class MyClass(object):\n" +
                "   def __init__(self, value):\n" +
                "       self.value = value\n");
        source.Execute(scope);

        var Add= scope.GetVariable<Func<object, object , object>>("Add");
        Console.WriteLine(Add(2,3 ));

But what I would like to have is var Add= scope.GetVariable<Func<functionTypes, functionTypes , functionTypes>>("Add"); where functionTypes represents int.

EDIT: Is there a solution which works for functions with arbitrary inputs. For instance, we want to translate an arbirtary function in python to the same function in c# (including all the types)

user16756428
  • 121
  • 2

1 Answers1

0

The easiest way to deal with it is using a manual casting. You can get C# clr type from IronPython using clr() method, then you can create if statement to create specific Func type (like in this post). You can also try to find a C# reflection solution (read this post) but in case of making Func<yourType, yourType, yourType> it could be extremly hard.

static void Main(string[] args)
{
    var engine = Python.CreateEngine();
    var scope = engine.CreateScope();
    var source = engine.CreateScriptSourceFromString(
            "def Add(arg1, arg2):\n" +
            "   return arg1 +1\n" +
            "\n" +
            "functionTypes = int" +
            "\n" +
            "class MyClass(object):\n" +
            "   def __init__(self, value):\n" +
            "       self.value = value\n");
    source.Execute(scope);
    var type = scope.GetVariable("functionTypes") as IronPython.Runtime.Types.PythonType;
    Type clrType = type.__clrtype__();
    if (clrType == typeof(int))
    {
        var Add = scope.GetVariable<Func<int, int, int>>("Add");
        Console.WriteLine(Add(2, 3));
    }
    else if (clrType == typeof(double))
    {
        var Add = scope.GetVariable<Func<double, double, double>>("Add");
        Console.WriteLine(Add(2, 3));
    }
    //make your own else statements here
}
ElConrado
  • 1,477
  • 4
  • 20
  • 46
  • This approach works fairly well in the example I gave above. But let's assume we have an arbitrary function with arbitrary arguments in python. And we want to extract this function from the python script. Do you see a solution for that? – user16756428 Aug 26 '21 at 16:48
  • You can get by: var func = scope.GetVariable("Add"); , but you need to know type if you want to parse in C#, instead you only get dynamic type. Anyway, I think you can try reflection but I also think it will be very hard in case of function extraction. – ElConrado Aug 27 '21 at 07:20