Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IronPython overload resolution on generic types

Tags:

ironpython

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

like image 521
bigh_29 Avatar asked Oct 11 '10 16:10

bigh_29


2 Answers

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.

like image 116
Jeff Mercado Avatar answered Oct 13 '22 01:10

Jeff Mercado


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!

like image 34
konrad Avatar answered Oct 13 '22 02:10

konrad