@@ -321,37 +321,47 @@ private static void AddVirtualMethod(MethodInfo method, Type baseType, TypeBuild
321
321
ParameterInfo [ ] parameters = method . GetParameters ( ) ;
322
322
Type [ ] parameterTypes = ( from param in parameters select param . ParameterType ) . ToArray ( ) ;
323
323
324
- // create a method for calling the original method
325
- string baseMethodName = "_" + baseType . Name + "__" + method . Name ;
326
- MethodBuilder methodBuilder = typeBuilder . DefineMethod ( baseMethodName ,
327
- MethodAttributes . Public |
328
- MethodAttributes . Final |
329
- MethodAttributes . HideBySig ,
330
- method . ReturnType ,
331
- parameterTypes ) ;
332
-
333
- // emit the assembly for calling the original method using call instead of callvirt
334
- ILGenerator il = methodBuilder . GetILGenerator ( ) ;
335
- il . Emit ( OpCodes . Ldarg_0 ) ;
336
- for ( int i = 0 ; i < parameters . Length ; ++ i )
337
- il . Emit ( OpCodes . Ldarg , i + 1 ) ;
338
- il . Emit ( OpCodes . Call , method ) ;
339
- il . Emit ( OpCodes . Ret ) ;
324
+ // If the method isn't abstract create a method for calling the original method
325
+ string baseMethodName = null ;
326
+ if ( ! method . IsAbstract )
327
+ {
328
+ baseMethodName = "_" + baseType . Name + "__" + method . Name ;
329
+ MethodBuilder baseMethodBuilder = typeBuilder . DefineMethod ( baseMethodName ,
330
+ MethodAttributes . Public |
331
+ MethodAttributes . Final |
332
+ MethodAttributes . HideBySig ,
333
+ method . ReturnType ,
334
+ parameterTypes ) ;
335
+
336
+ // emit the assembly for calling the original method using call instead of callvirt
337
+ ILGenerator baseIl = baseMethodBuilder . GetILGenerator ( ) ;
338
+ baseIl . Emit ( OpCodes . Ldarg_0 ) ;
339
+ for ( int i = 0 ; i < parameters . Length ; ++ i )
340
+ baseIl . Emit ( OpCodes . Ldarg , i + 1 ) ;
341
+ baseIl . Emit ( OpCodes . Call , method ) ;
342
+ baseIl . Emit ( OpCodes . Ret ) ;
343
+ }
340
344
341
345
// override the original method with a new one that dispatches to python
342
- methodBuilder = typeBuilder . DefineMethod ( method . Name ,
343
- MethodAttributes . Public |
344
- MethodAttributes . ReuseSlot |
345
- MethodAttributes . Virtual |
346
- MethodAttributes . HideBySig ,
347
- method . CallingConvention ,
348
- method . ReturnType ,
349
- parameterTypes ) ;
350
- il = methodBuilder . GetILGenerator ( ) ;
346
+ MethodBuilder methodBuilder = typeBuilder . DefineMethod ( method . Name ,
347
+ MethodAttributes . Public |
348
+ MethodAttributes . ReuseSlot |
349
+ MethodAttributes . Virtual |
350
+ MethodAttributes . HideBySig ,
351
+ method . CallingConvention ,
352
+ method . ReturnType ,
353
+ parameterTypes ) ;
354
+ ILGenerator il = methodBuilder . GetILGenerator ( ) ;
351
355
il . DeclareLocal ( typeof ( Object [ ] ) ) ;
352
356
il . Emit ( OpCodes . Ldarg_0 ) ;
353
357
il . Emit ( OpCodes . Ldstr , method . Name ) ;
354
- il . Emit ( OpCodes . Ldstr , baseMethodName ) ;
358
+
359
+ // don't fall back to the base type's method if it's abstract
360
+ if ( null != baseMethodName )
361
+ il . Emit ( OpCodes . Ldstr , baseMethodName ) ;
362
+ else
363
+ il . Emit ( OpCodes . Ldnull ) ;
364
+
355
365
il . Emit ( OpCodes . Ldc_I4 , parameters . Length ) ;
356
366
il . Emit ( OpCodes . Newarr , typeof ( System . Object ) ) ;
357
367
il . Emit ( OpCodes . Stloc_0 ) ;
@@ -624,7 +634,7 @@ public static T InvokeMethod<T>(IPythonDerivedType obj, string methodName, strin
624
634
}
625
635
626
636
if ( origMethodName == null )
627
- throw new NullReferenceException ( "Python object does not have a '" + methodName + "' method" ) ;
637
+ throw new NotImplementedException ( "Python object does not have a '" + methodName + "' method" ) ;
628
638
629
639
return ( T ) obj . GetType ( ) . InvokeMember ( origMethodName ,
630
640
BindingFlags . InvokeMethod ,
@@ -683,7 +693,7 @@ public static void InvokeMethodVoid(IPythonDerivedType obj, string methodName, s
683
693
}
684
694
685
695
if ( origMethodName == null )
686
- throw new NullReferenceException ( "Python object does not have a '" + methodName + "' method" ) ;
696
+ throw new NotImplementedException ( "Python object does not have a '" + methodName + "' method" ) ;
687
697
688
698
obj . GetType ( ) . InvokeMember ( origMethodName ,
689
699
BindingFlags . InvokeMethod ,
0 commit comments