Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(Iron)Python - defining a variable of specific type

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:

  • Is it possible to get this to run?
  • How???

Thanks a lot!!

like image 481
Traummaennlein Avatar asked Dec 22 '22 05:12

Traummaennlein


1 Answers

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
like image 152
Jeff Mercado Avatar answered Dec 27 '22 09:12

Jeff Mercado