@@ -1152,6 +1152,206 @@ def call_method():
11521152 Assert . AreEqual ( "MethodWithEnumParam With Enum" , result . As < string > ( ) ) ;
11531153 }
11541154
1155+ [ Test ]
1156+ public void BindsPythonToCSharpFuncDelegates ( )
1157+ {
1158+ using var _ = Py . GIL ( ) ;
1159+
1160+ var module = PyModule . FromString ( "BindsPythonToCSharpFuncDelegates" , @$ "
1161+ from clr import AddReference
1162+ AddReference(""System"")
1163+ from Python.EmbeddingTest import *
1164+
1165+ from System import Func
1166+
1167+ class PythonModel:
1168+ last_delegate_called = None
1169+
1170+ def func1():
1171+ PythonModel.last_delegate_called = 'func1'
1172+ return TestMethodBinder.CSharpModel();
1173+
1174+ def func2(model):
1175+ if model is None or not isinstance(model, TestMethodBinder.CSharpModel):
1176+ raise TypeError(""model must be of type CSharpModel"")
1177+ PythonModel.last_delegate_called = 'func2'
1178+ return model
1179+
1180+ def func3(model1, model2):
1181+ if model1 is None or model2 is None or not isinstance(model1, TestMethodBinder.CSharpModel) or not isinstance(model2, TestMethodBinder.CSharpModel):
1182+ raise TypeError(""model1 and model2 must be of type CSharpModel"")
1183+ PythonModel.last_delegate_called = 'func3'
1184+ return model1
1185+
1186+ def call_method_with_func1():
1187+ return TestMethodBinder.CSharpModel.MethodWithFunc1(func1)
1188+
1189+ def call_method_with_func2():
1190+ return TestMethodBinder.CSharpModel.MethodWithFunc2(func2)
1191+
1192+ def call_method_with_func3():
1193+ return TestMethodBinder.CSharpModel.MethodWithFunc3(func3)
1194+
1195+ def call_method_with_func1_lambda():
1196+ return TestMethodBinder.CSharpModel.MethodWithFunc1(lambda: func1())
1197+
1198+ def call_method_with_func2_lambda():
1199+ return TestMethodBinder.CSharpModel.MethodWithFunc2(lambda model: func2(model))
1200+
1201+ def call_method_with_func3_lambda():
1202+ return TestMethodBinder.CSharpModel.MethodWithFunc3(lambda model1, model2: func3(model1, model2))
1203+ " ) ;
1204+
1205+ using var pythonModel = module . GetAttr ( "PythonModel" ) ;
1206+
1207+ var assertCalledMethods = ( string csharpCalledMethod , string pythonCalledMethod ) =>
1208+ {
1209+ Assert . AreEqual ( csharpCalledMethod , CSharpModel . LastDelegateCalled ) ;
1210+ var lastDelegateCalled = pythonModel . GetAttr ( "last_delegate_called" ) ;
1211+ Assert . AreEqual ( pythonCalledMethod , lastDelegateCalled . As < string > ( ) ) ;
1212+ lastDelegateCalled . Dispose ( ) ;
1213+ } ;
1214+
1215+ Assert . DoesNotThrow ( ( ) =>
1216+ {
1217+ using var result = module . GetAttr ( "call_method_with_func1" ) . Invoke ( ) ;
1218+ var managedResult = result . As < CSharpModel > ( ) ;
1219+ } ) ;
1220+ assertCalledMethods ( "MethodWithFunc1" , "func1" ) ;
1221+
1222+ Assert . DoesNotThrow ( ( ) =>
1223+ {
1224+ using var result = module . GetAttr ( "call_method_with_func2" ) . Invoke ( ) ;
1225+ var managedResult = result . As < CSharpModel > ( ) ;
1226+ } ) ;
1227+ assertCalledMethods ( "MethodWithFunc2" , "func2" ) ;
1228+
1229+ Assert . DoesNotThrow ( ( ) =>
1230+ {
1231+ using var result = module . GetAttr ( "call_method_with_func3" ) . Invoke ( ) ;
1232+ var managedResult = result . As < CSharpModel > ( ) ;
1233+ } ) ;
1234+ assertCalledMethods ( "MethodWithFunc3" , "func3" ) ;
1235+
1236+ Assert . DoesNotThrow ( ( ) =>
1237+ {
1238+ using var result = module . GetAttr ( "call_method_with_func1_lambda" ) . Invoke ( ) ;
1239+ var managedResult = result . As < CSharpModel > ( ) ;
1240+ } ) ;
1241+ assertCalledMethods ( "MethodWithFunc1" , "func1" ) ;
1242+
1243+ Assert . DoesNotThrow ( ( ) =>
1244+ {
1245+ using var result = module . GetAttr ( "call_method_with_func2_lambda" ) . Invoke ( ) ;
1246+ var managedResult = result . As < CSharpModel > ( ) ;
1247+ } ) ;
1248+ assertCalledMethods ( "MethodWithFunc2" , "func2" ) ;
1249+
1250+ Assert . DoesNotThrow ( ( ) =>
1251+ {
1252+ using var result = module . GetAttr ( "call_method_with_func3_lambda" ) . Invoke ( ) ;
1253+ var managedResult = result . As < CSharpModel > ( ) ;
1254+ } ) ;
1255+ assertCalledMethods ( "MethodWithFunc3" , "func3" ) ;
1256+ }
1257+
1258+ [ Test ]
1259+ public void BindsPythonToCSharpActionDelegates ( )
1260+ {
1261+ using var _ = Py . GIL ( ) ;
1262+
1263+ var module = PyModule . FromString ( "BindsPythonToCSharpActionDelegates" , @$ "
1264+ from clr import AddReference
1265+ AddReference(""System"")
1266+ from Python.EmbeddingTest import *
1267+
1268+ from System import Func
1269+
1270+ class PythonModel:
1271+ last_delegate_called = None
1272+
1273+ def action1():
1274+ PythonModel.last_delegate_called = 'action1'
1275+ pass
1276+
1277+ def action2(model):
1278+ if model is None or not isinstance(model, TestMethodBinder.CSharpModel):
1279+ raise TypeError(""model must be of type CSharpModel"")
1280+ PythonModel.last_delegate_called = 'action2'
1281+ pass
1282+
1283+ def action3(model1, model2):
1284+ if model1 is None or model2 is None or not isinstance(model1, TestMethodBinder.CSharpModel) or not isinstance(model2, TestMethodBinder.CSharpModel):
1285+ raise TypeError(""model1 and model2 must be of type CSharpModel"")
1286+ PythonModel.last_delegate_called = 'action3'
1287+ pass
1288+
1289+ def call_method_with_action1():
1290+ return TestMethodBinder.CSharpModel.MethodWithAction1(action1)
1291+
1292+ def call_method_with_action2():
1293+ return TestMethodBinder.CSharpModel.MethodWithAction2(action2)
1294+
1295+ def call_method_with_action3():
1296+ return TestMethodBinder.CSharpModel.MethodWithAction3(action3)
1297+
1298+ def call_method_with_action1_lambda():
1299+ return TestMethodBinder.CSharpModel.MethodWithAction1(lambda: action1())
1300+
1301+ def call_method_with_action2_lambda():
1302+ return TestMethodBinder.CSharpModel.MethodWithAction2(lambda model: action2(model))
1303+
1304+ def call_method_with_action3_lambda():
1305+ return TestMethodBinder.CSharpModel.MethodWithAction3(lambda model1, model2: action3(model1, model2))
1306+ " ) ;
1307+
1308+ using var pythonModel = module . GetAttr ( "PythonModel" ) ;
1309+
1310+ var assertCalledMethods = ( string csharpCalledMethod , string pythonCalledMethod ) =>
1311+ {
1312+ Assert . AreEqual ( csharpCalledMethod , CSharpModel . LastDelegateCalled ) ;
1313+ var lastDelegateCalled = pythonModel . GetAttr ( "last_delegate_called" ) ;
1314+ Assert . AreEqual ( pythonCalledMethod , lastDelegateCalled . As < string > ( ) ) ;
1315+ lastDelegateCalled . Dispose ( ) ;
1316+ } ;
1317+
1318+ Assert . DoesNotThrow ( ( ) =>
1319+ {
1320+ using var result = module . GetAttr ( "call_method_with_action1" ) . Invoke ( ) ;
1321+ } ) ;
1322+ assertCalledMethods ( "MethodWithAction1" , "action1" ) ;
1323+
1324+ Assert . DoesNotThrow ( ( ) =>
1325+ {
1326+ using var result = module . GetAttr ( "call_method_with_action2" ) . Invoke ( ) ;
1327+ } ) ;
1328+ assertCalledMethods ( "MethodWithAction2" , "action2" ) ;
1329+
1330+ Assert . DoesNotThrow ( ( ) =>
1331+ {
1332+ using var result = module . GetAttr ( "call_method_with_action3" ) . Invoke ( ) ;
1333+ } ) ;
1334+ assertCalledMethods ( "MethodWithAction3" , "action3" ) ;
1335+
1336+ Assert . DoesNotThrow ( ( ) =>
1337+ {
1338+ using var result = module . GetAttr ( "call_method_with_action1_lambda" ) . Invoke ( ) ;
1339+ } ) ;
1340+ assertCalledMethods ( "MethodWithAction1" , "action1" ) ;
1341+
1342+ Assert . DoesNotThrow ( ( ) =>
1343+ {
1344+ using var result = module . GetAttr ( "call_method_with_action2_lambda" ) . Invoke ( ) ;
1345+ } ) ;
1346+ assertCalledMethods ( "MethodWithAction2" , "action2" ) ;
1347+
1348+ Assert . DoesNotThrow ( ( ) =>
1349+ {
1350+ using var result = module . GetAttr ( "call_method_with_action3_lambda" ) . Invoke ( ) ;
1351+ } ) ;
1352+ assertCalledMethods ( "MethodWithAction3" , "action3" ) ;
1353+ }
1354+
11551355 // Used to test that we match this function with Py DateTime & Date Objects
11561356 public static int GetMonth ( DateTime test )
11571357 {
@@ -1288,6 +1488,50 @@ public static void MethodDateTimeAndTimeSpan(CSharpModel pepe, Func<DateTime, Da
12881488 {
12891489 AssertErrorNotOccurred ( ) ;
12901490 }
1491+
1492+ public static string LastDelegateCalled { get ; private set ; }
1493+
1494+ public static CSharpModel MethodWithFunc1 ( Func < CSharpModel > func )
1495+ {
1496+ AssertErrorNotOccurred ( ) ;
1497+ LastDelegateCalled = "MethodWithFunc1" ;
1498+ return func ( ) ;
1499+ }
1500+
1501+ public static CSharpModel MethodWithFunc2 ( Func < CSharpModel , CSharpModel > func )
1502+ {
1503+ AssertErrorNotOccurred ( ) ;
1504+ LastDelegateCalled = "MethodWithFunc2" ;
1505+ return func ( new CSharpModel ( ) ) ;
1506+ }
1507+
1508+ public static CSharpModel MethodWithFunc3 ( Func < CSharpModel , CSharpModel , CSharpModel > func )
1509+ {
1510+ AssertErrorNotOccurred ( ) ;
1511+ LastDelegateCalled = "MethodWithFunc3" ;
1512+ return func ( new CSharpModel ( ) , new CSharpModel ( ) ) ;
1513+ }
1514+
1515+ public static void MethodWithAction1 ( Action action )
1516+ {
1517+ AssertErrorNotOccurred ( ) ;
1518+ LastDelegateCalled = "MethodWithAction1" ;
1519+ action ( ) ;
1520+ }
1521+
1522+ public static void MethodWithAction2 ( Action < CSharpModel > action )
1523+ {
1524+ AssertErrorNotOccurred ( ) ;
1525+ LastDelegateCalled = "MethodWithAction2" ;
1526+ action ( new CSharpModel ( ) ) ;
1527+ }
1528+
1529+ public static void MethodWithAction3 ( Action < CSharpModel , CSharpModel > action )
1530+ {
1531+ AssertErrorNotOccurred ( ) ;
1532+ LastDelegateCalled = "MethodWithAction3" ;
1533+ action ( new CSharpModel ( ) , new CSharpModel ( ) ) ;
1534+ }
12911535 }
12921536
12931537 public class TestImplicitConversion
0 commit comments