将列表从IronPython传递到C#

passing Lists from IronPython to C#

我想将字符串列表从Ironpython 2.6 for.NET 2.0传递给C程序(我使用的是.NET 2.0,因为我使用的是一个运行在2.0上构建的DLL的API)。但我不知道如何在脚本引擎返回时对其进行强制转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
namespace test1
{
    class Program
    {
        static void Main(string[] args)
        {
            ScriptEngine engine = Python.CreateEngine();
            ScriptSource source = engine.CreateScriptSourceFromFile("C:\\File\\Path\\To\\my\\script.py");
            ScriptScope scope = engine.CreateScope();

            ObjectOperations op = engine.Operations;

            source.Execute(scope); // class object created
            object classObject = scope.GetVariable("MyClass"); // get the class object
            object instance = op.Invoke(classObject); // create the instance
            object method = op.GetMember(instance,"myMethod"); // get a method
            List<string> result = (List<string>)op.Invoke(method); // call the method and get result
            Console.WriteLine(result.ToString());
            Console.Read();
        }
    }
}

我的python代码有一个类,该类的方法返回字符串的python列表:

1
2
3
class MyClass(object):
    def myMethod(self):
        return ['a','list','of','strings']

我得到这个错误:

1
Unable to cast object of type 'IronPython.Runtime.List' to type 'System.Collections.Generic.List`1[System.String]'.


IronPython.Runtime.List实现以下接口:

1
IList, ICollection, IList<object>, ICollection<object>, IEnumerable<object>, IEnumerable

因此,您可以强制转换为这种类型之一,然后转换为List

1
List<string> result = ((IList<object>)op.Invoke(method)).Cast<string>().ToList();

顺便说一句,也许你知道,但是你也可以在Ironpython中使用.NET类型,例如:

1
2
3
4
5
from System.Collections.Generic import *

class MyClass(object):
    def myMethod(self):
        return List[str](['a','list','of','strings'])

这里,myMethod直接返回List

编辑:

考虑到您使用的是.NET 2.0(所以没有LINQ),您有两个选项(IMO):

1。铸造至IList并使用:

1
IList<object> result = (IList<object>)op.Invoke(method);

优点:不需要循环,您将使用由python脚本返回的相同对象实例。缺点:没有类型安全性(您将像在Python中一样,因此您也可以向列表中添加非字符串)

2。转换为List/IList

1
2
3
4
5
6
IList<object> originalResult = (IList<object>)op.Invoke(method);
List<string> typeSafeResult = new List<string>();
foreach(object element in originalResult)
{
    typeSafeResult.Add((string)element);
}

优点:键入安全列表(只能添加字符串)。缺点:它需要一个循环,转换后的列表是一个新实例(脚本返回的实例不同)