IronPython overload resolution on generic types
Asked Answered
B

2

6

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

Bolshevist answered 11/10, 2010 at 16:2 Comment(0)
P
10

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.

Philippe answered 11/10, 2010 at 16:36 Comment(0)
H
1

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!

Hallowed answered 25/1, 2016 at 22:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.