I have a C# class with overloaded static methods like these:
// Added to the Simple class in Tutorial\Extend\csextend.cs
public static int Foo(IEnumerable<int> values)
{
return 1;
}
public static int Foo(IEnumerable<string> values)
{
return 2;
}
I get an error when I try to call these from IronPython 2.6. I am passing a python list that contains strings.
import clr
clr.AddReferenceToFile("csextend.dll")
import Simple
Simple.Foo(["alpha", "bravo", "charlie"])
TypeError: Multiple targets could match: Foo(IEnumerable[str]), Foo(IEnumerable[ int])
My first question is why doesn't this work? It seems like overload resolution should work on this. Is this a bug in IronPython? What is the cleanest workaround. I could rename the routines so they don't overload each other, but then I am letting ironpython quirks alter the design of the C# class.
Is there a clean way to give python a clue that the list is entirely composed of one type, and that it should pick a specific overload?
Related to this question
IronPython doesn't really have overloads of functions, just one single function with all the functionality. Normally IronPython would do this automatically but the generic types complicate things. To disambiguate which overload to use, get the function using the Overloads
dictionary passing the types in the signature as the key. (I'm using IronPython 2.7 at the time of writing this so I don't know if there's a difference between version 2.6 and 2.7)
import System.Collections.Generic.IEnumerable as IEnumerable
Simple.Foo.Overloads[IEnumerable[str]](["alpha", "bravo", "charlie"])
If there were more parameters in the functions, pass the types in as a tuple.
#public static int Foo(IEnumerable<string> values, string otherParam)
#{
# return 3;
#}
Simple.Foo.Overloads[IEnumerable[str],str](["alpha", "bravo", "charlie"], "x")
etc.
I know this wasn't the OP's exact question, but here's a similar scenario with overloads and multiple parameters just in case someone else is wondering how to solve it:
public FamilyInstance NewFamilyInstance(
XYZ origin,
FamilySymbol symbol,
View specView
)
public FamilyInstance NewFamilyInstance(
Line line,
FamilySymbol symbol,
View specView
)
And here's how to call it with a specific overload that uses Line instead of XYZ:
doc.Create.NewFamilyInstance.Overloads[Line, FamilySymbol, View](crv, symbol, view)
This post helped me a lot. Thanks for sharing!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With