在Python中创建一个C#Nullable Int32(使用Python.NET)来调用带有可选int参数的C#方法

在Python中创建一个C#Nullable Int32(使用Python.NET)来调用带有可选int参数的C#方法,c#,python,.net,optional-arguments,python.net,C#,Python,.net,Optional Arguments,Python.net,我使用加载一个C程序集来从Python调用C代码。这工作得非常干净,但是我在调用一个方法时遇到了一个问题,如下所示: 我们的.Namespace.Proj.MyRepo中的方法: OutputObject GetData(string user, int anID, int? anOptionalID= null) 对于存在可选的第三个参数的情况,我可以调用该方法,但无法确定为第三个参数传递什么来匹配空的情况 import clr clr.AddReference("Our.Namespace

我使用加载一个C程序集来从Python调用C代码。这工作得非常干净,但是我在调用一个方法时遇到了一个问题,如下所示:

我们的.Namespace.Proj.MyRepo中的方法:

OutputObject GetData(string user, int anID, int? anOptionalID= null)
对于存在可选的第三个参数的情况,我可以调用该方法,但无法确定为第三个参数传递什么来匹配空的情况

import clr
clr.AddReference("Our.Namespace.Proj")
import System
from Our.Namespace.Proj import MyRepo

_repo = MyRepo()

_repo.GetData('me', System.Int32(1), System.Int32(2))  # works!

_repo.GetData('me', System.Int32(1))  # fails! TypeError: No method matches given arguments

_repo.GetData('me', System.Int32(1), None)  # fails! TypeError: No method matches given arguments
iPython笔记本指出最后一个参数的类型应为:

System.Nullable`1[System.Int32]
只是不确定如何创建一个与空大小写匹配的对象


关于如何创建C#可识别的空对象,有什么建议吗?我认为传递本机Python不会有任何效果,但事实并非如此。

我无法测试这一点,但请尝试

_repo.GetData('me', System.Int32(1), System.Nullable[System.Int32]())
因为您说可选参数是
Nullable
,所以需要创建一个新的
Nullable
对象,类型为
Int32
,或者在C#code中创建
new System.Nullable()

我假设第一个失败的例子会起作用,因为这是可选参数在C#中的工作方式;在不指定参数的情况下调用函数。

[EDIT]

这已合并到pythonnet:


我在使用可空原语时遇到了同样的问题——在我看来,Python.NET不支持这些类型。通过在Python.Runtime.Converter.ToManagedValue()中添加以下代码(\src\Runtime\Converter.cs),我绕过了这个问题


您必须将参数传递给泛型函数
System.Nullable[System.Int32](0)

谢谢您的建议。当我尝试创建
System.Nullable[System.Int32]()
时,即使在对GetData的调用之外,我也会得到一个
TypeError:没有构造函数与给定的参数匹配。我还尝试只传入
System.Nullable[System.Int32]
,这给了我
ArgumentException:类型为“System.RuntimeType”的对象无法转换为类型为“System.Nullable`1[System.Int32]”。
奇怪。我不熟悉Python语法,不确定
'1
在那里做什么。希望有比我聪明的人能破解这个难题。我最初认为您使用的是IronPython,您可能想尝试一下,因为它似乎可以更好地处理可选参数。这不是Python语法,这是泛型类型的.NET语法-`1表示1个类型参数。我明白了。我不知道为什么Python.NET会被阻塞。我不知道Python.NET,但似乎当你不给它传递任何信息时,它可能只搜索带有引用类型参数的方法。您至少可以在没有最后一个参数的情况下尝试重载(可能还有另一个重载,最后一个参数是
object
,允许传递None(如果这样做有效的话),然后用最后一个参数
作为int调用第一个方法?
)最终重构C端,使其具有重载方法(一个带第三个参数,一个不带第三个参数).Python.NET处理得很好。缺点是我必须根据最后一个参数的存在有条件地调用两个方法中的一个。对于C#端的第三个重载情况,我将尝试将最后一个参数设置为
object
,以允许不传递任何方法。谢谢!您是说您修改了Python.NET源代码吗?Y是的,我指的是中的Python.NET源代码。明白了。谢谢!我将总结这个问题并发布到,以便它可以集成到下一个版本中。
if( obType.IsGenericType && obType.GetGenericTypeDefinition() == typeof(Nullable<>) )
{
    if( value == Runtime.PyNone )
    {
        result = null;
        return true;
    }
    // Set type to underlying type
    obType = obType.GetGenericArguments()[0];
}
if (value == Runtime.PyNone && !obType.IsValueType) {
    result = null;
    return true;
}