views:

148

answers:

2

I am trying to assign an IronPython instance method to a C# Func<Foo> parameter.

In C# I would have a method like:

public class CSharpClass
{
    public void DoSomething(Func<Foo> something)
    {
        var foo = something()
    }
}

And call it from IronPython like this:

class IronPythonClass:
    def foobar(self):
        return Foo()
CSharpClass().DoSomething(foobar)

But I'm getting the following error:

TypeError: expected Func[Foo], got instancemethod

+1  A: 

OK. I think I might have found a solution:

import clr
clr.AddReference('System')
clr.AddReference('System.Core')

from System import Func

class IronPythonClass:
def foobar(self):
    return Foo()

CSharpClass().DoSomething(Func[Foo](foobar))

The interesting bit is the Func[Foo]constructor :)

Daren Thomas
A: 

The first option is to use a static method. For that you'll have to use the @staticmethod decorator:

class IronPythonClass: 
    @staticmethod
    def foobar(): 
         return Foo() 

CSharpClass().DoSomething(IronPythonClass.foobar)

If you do want it to be an instance method, then you can use a bound method:

class IronPythonClass: 
    def foobar(self): 
         return Foo() 

ipc = IronPythonClass()
CSharpClass().DoSomething(ipc.foobar) # using ipc.foobar binds 'ipc' to the 'self' parameter

Finally, you should be able to take a Func<object, Foo> instead and pass the instance method as you originally tried to do.

Jeff Hardy
whoops. Missed the `self` part in my example.
Daren Thomas
but I maintain that the runtime checks the type, so you have to wrap `IronPythonClass.foobar` in a `Func[Foo]`.
Daren Thomas
Which version of IronPython are you using? The second example (bound method) works for me w/ 2.6.0.
Jeff Hardy