yes I know, this seems to be the same question as asked thousands of times before. But no, it's not really - at least I think so.
I use IronPython and want to call a C# method:
bool GetClassInstance<T>(out T myClassInstance)
Calling this function via python would look like:
myClassInstance = None
myInstance.GetClassInstance[ClassType](myClassInstance)
The problem is following error message:
expected StrongBox[ClassType], got NoneType (ArgumentTypeException)
Now I do have two questions:
Thanks a lot!!
To call methods that have out
parameters, just omit the argument (as you're not really passing a value) and its return value will be a tuple with the result of the function (if it was non-void
) and the out
values in the order they are defined.
In the case of ref
parameters, pass in the argument and it will still be returned in the tuple. Any mutations on the object will work as expected.
e.g.,
>>> from System import Int32
>>> Int32.TryParse('12345')
(True, 12345)
>>> Int32.TryParse('12345x')
(False, 0)
Here's a test I did so you could see how to call the different variations.
namespace TestLibrary
{
public class Test
{
public static void Test1(out int b)
{
b = 1;
}
public static bool Test2(out int b)
{
b = 2;
return b == 2;
}
public static void Test3(int a, out int b, int c)
{
b = a + c;
}
public static bool Test4(int a, out int b, int c)
{
b = a + c;
return b == 4;
}
public static void Test5(int a, out int b, int c, out int d)
{
b = a + c;
d = a * c;
}
public static bool Test6(int a, out int b, int c, out int d)
{
b = a + c;
d = a * c;
return b == 6 || d == 6;
}
public static void Test7(int a, out int b, int c, out int d, ref int e)
{
b = a + c;
d = a * c;
int oldE = e++;
Console.WriteLine("\"{0}\" -> \"{1}\"", oldE, e);
}
public static bool Test8(int a, out int b, int c, out int d, ref int e)
{
b = a + c;
d = a * c;
int oldE = e++;
Console.WriteLine("\"{0}\" -> \"{1}\"", oldE, e);
return b == 8 || d == 8 || oldE == 8;
}
public static bool Test9(int a, out int b, int c, out int d, ref int e, ref int[] f)
{
b = a + c;
d = a * c;
int oldE = e++;
Console.WriteLine("\"{0}\" -> \"{1}\"", oldE, e);
f = f ?? new int[0];
for (int i = 0; i < f.Length; i++)
f[i] = i;
return b == 8 || d == 8 || oldE == 8;
}
}
}
>>> from TestLibrary import Test
>>> Test.Test1()
1
>>> Test.Test2()
(True, 2)
>>> Test.Test3(1, 3)
4
>>> Test.Test4(1, 3)
(True, 4)
>>> Test.Test5(1, 3)
(4, 3)
>>> Test.Test6(1, 3)
(False, 4, 3)
>>> Test.Test7(1, 3, 5)
"5" -> "6"
(4, 3, 6)
>>> Test.Test8(1, 3, 5)
"5" -> "6"
(False, 4, 3, 6)
>>> from System import Array
>>> array = Array.CreateInstance(int, 10)
>>> array
Array[int]((0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
>>> Test.Test9(1, 3, 5, array)
"5" -> "6"
(False, 4, 3, 6, Array[int]((0, 1, 2, 3, 4, 5, 6, 7, 8, 9)))
>>> array
Array[int]((0, 1, 2, 3, 4, 5, 6, 7, 8, 9))
Alternatively if you wanted to use the C# style call, you need to pass in a clr.Reference[T]
object in place of the out
/ref
parameter to hold the value. You can access that value through the Value
property.
>>> outval = clr.Reference[int]()
>>> Test.Test1(outval)
>>> outval
<System.Int32 object at 0x000000000000002B [1]>
>>> outval.Value
1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With