(Iron) Python - Defining a variable of a specific type

Yes, I know, this seems to be the same question as a thousand times. But no, thatโ€™s not really - at least I think so.

I am using IronPython and want to call the C # method:

bool GetClassInstance<T>(out T myClassInstance) 

A call to this function through python will look like this:

 myClassInstance = None myInstance.GetClassInstance[ClassType](myClassInstance) 

The problem is the following error message:

 expected StrongBox[ClassType], got NoneType (ArgumentTypeException) 

Now I have two questions:

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

Thanks a lot!

+4
source share
2 answers

To call methods with out parameters, simply omit the argument (since you really do not pass a value), and its return value will be a tuple with the result of the function (if it was not void ) and out in the order in which they are defined.

For ref parameters, pass an argument, and it will still be returned to the tuple. Any mutations at the facility will work as expected.

eg.

 >>> from System import Int32 >>> Int32.TryParse('12345') (True, 12345) >>> Int32.TryParse('12345x') (False, 0) 

In this test, I made it so that you can see how to call different options.

 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 want to use a C # style call, you need to pass the clr.Reference[T] object instead of the out / ref parameter to save the value. You can access this value using the Value property.

 >>> outval = clr.Reference[int]() >>> Test.Test1(outval) >>> outval <System.Int32 object at 0x000000000000002B [1]> >>> outval.Value 1 
+8
source

Jeff's answer is good, but if you really want to use ref / out semantics, then you can use the StrongBox type (accessible via clr.StrongBox, but this is the same StrongBox that uses LINQ):

 import clr myClassInstance = clr.StrongBox[ClassType]() myInstance.GetClassInstance[ClassType](myClassInstance) print myClassInstance.Value # value is now updated 

This allows you to use odd scripts, for example, when a function is overloaded and differs only in the ref / out parameters, or when you want to view a value in another thread, updated before GetClassInstance returns.

+2
source

Source: https://habr.com/ru/post/1384859/


All Articles