This is easy to work with using dynamic
:
var ipy = Python.CreateRuntime();
dynamic test = ipy.UseFile("test.py");
foreach (int n in test.do_yield())
{
Console.WriteLine("py gen returned: " + n);
}
// outputs
py gen returned: 1
py gen returned: 2
py gen returned: 3
The one big thing you should note is that extension methods (like LINQ) don't work with dynamic
, since extension methods are just static method calls with some syntactic sugar applied. And the object in this case implements IEnumerable
but not IEnumerable<int>
, limiting your options for how to deal with this.
Let's say you want to filter the items to even ones. This is one way to do it:
var ipy = Python.CreateRuntime();
dynamic test = ipy.UseFile("test.py");
foreach (int n in test.do_yield())
{
if (n % 2 == 0)
Console.WriteLine("py gen returned: " + n);
}
Or you can cast and then use LINQ extension methods (this works because the IEnumerable
cast lets the rest of the code be evaluated at compile time, like non-dynamic code):
var ipy = Python.CreateRuntime();
dynamic test = ipy.UseFile("test.py");
foreach (int n in ((IEnumerable)test.do_yield()).Cast<int>().Where(n => n % 2 == 0))
{
Console.WriteLine("py gen returned: " + n);
}
In some instances, you might wish to use extension methods without their syntactic sugar, e.g.
// these lines are generally equivalent, unless someList is dynamic
var filteredList = Enumerable.Where(someList, x => x % 2 == 0);
var filteredList = someList.Where(x => x % 2 == 0);