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

本文关键字:Python 调用 参数 方法 int NET 创建 一个 C#Nullable 使用 Int32 | 更新日期: 2023-09-27 18:29:01

我正在使用Python.NET加载一个C#程序集,以便从Python中调用C#代码。这非常干净,但是我在调用一个看起来像这样的方法时遇到了问题:

我们的命名空间.Proj.MyRepo:中的一种方法

OutputObject GetData(string user, int anID, int? anOptionalID= null)

对于存在可选的第三个参数的情况,我可以调用该方法,但无法确定为第三个自变量传递什么以匹配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]

只是不确定如何创建一个匹配Null大小写的对象。

关于如何创建C#识别的Null对象,有什么建议吗?我以为传递本机Python None会起作用,但事实并非如此。

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

[EDIT]

这已经被合并到pythonnet:

https://github.com/pythonnet/pythonnet/pull/460


我在可为null的基元方面遇到了同样的问题——在我看来,Python.NET不支持这些类型。我通过在Python.Runtime.Converter.ToManagedValue()(''src''Runtime''Converter.cs)中添加以下代码来解决这个问题

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;
}

https://github.com/pythonnet/pythonnet/blob/4df6105b98b302029e524c7ce36f7b3cb18f7040/src/runtime/converter.cs#L320

我没有办法测试这个,但尝试

_repo.GetData('me', System.Int32(1), System.Nullable[System.Int32]())

由于您说可选参数是Nullable,因此需要在C#代码中创建一个类型为Int32new System.Nullable<int>()的新Nullable对象。

我本以为第一个失败的例子会起作用,因为C#中的可选参数就是这样工作的;调用函数时根本不指定参数。

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