简体   繁体   中英

Python NET call C# method which has a return value and an out parameter

I'm having the following static C# method

public static bool TryParse (string s, out double result)

which I would like to call from Python using the Python NET package.

import clr
from System import Double
r0 = Double.IsNaN(12.3) # works

r1, d1 = Double.TryParse("12.3") # fails! TypeError: No method matches given arguments. This works in IronPython.

d2 = 0.0
r2, d2 = Double.TryParse("12.3", d2) # fails! TypeError: No method matches given arguments

Any idea?

Update

I found the following answer, see https://stackoverflow.com/a/19600349/7556646 .

CPython using PythonNet does basically the same thing. The easy way to do out parameters is to not pass them and accept them as extra return values, and for ref parameters to pass the input values as arguments and accept the output values as extra return values.

This would claim that r1, d1 = Double.TryParse("12.3") should work, but it doesn't.

I had to address a similar problem recently with using Python for .NET , let me share with you what I have found out.

You need to pass as many arguments as the method requires to. Since the concept of out arguments (= passed by refence) doesn't apply to Python, the trick is to pass some dummy arguments of the expected type.

The method call is going to return first the values that it is supposed to return, and the out values.

For my use case, the C# method I was calling did not return anything originally (void method), yet, the Python call returned first None and then the out values I was after, which is the expected behaviour as stated here .

Your first attempt could not work because you pass only one argument, while the method expects two, be they out or ref arguments.

r1, d1 = Double.TryParse("12.3")

Your second attempt could not work either because the type of the dummy argument does not match with the type expected by the method, in that case Double .

d2 = 0.0
r2, d2 = Double.TryParse("12.3", d)

This will do the trick:

import clr
from System import Double
dummy_out = Double(0.)
returned_val, real_out = Double.TryParse("12.3", dummy_out)

You can observe that this last line does not have any effect on dummy_out by checking its id before and after the call.

Hence, a shorter version of the code you need would be:

returned_val, real_out = Double.TryParse("12.3", Double(0.))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM