@@ -321,37 +321,47 @@ private static void AddVirtualMethod(MethodInfo method, Type baseType, TypeBuild
321321 ParameterInfo [ ] parameters = method . GetParameters ( ) ;
322322 Type [ ] parameterTypes = ( from param in parameters select param . ParameterType ) . ToArray ( ) ;
323323
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+ }
340344
341345 // 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 ( ) ;
351355 il . DeclareLocal ( typeof ( Object [ ] ) ) ;
352356 il . Emit ( OpCodes . Ldarg_0 ) ;
353357 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+
355365 il . Emit ( OpCodes . Ldc_I4 , parameters . Length ) ;
356366 il . Emit ( OpCodes . Newarr , typeof ( System . Object ) ) ;
357367 il . Emit ( OpCodes . Stloc_0 ) ;
@@ -624,7 +634,7 @@ public static T InvokeMethod<T>(IPythonDerivedType obj, string methodName, strin
624634 }
625635
626636 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" ) ;
628638
629639 return ( T ) obj . GetType ( ) . InvokeMember ( origMethodName ,
630640 BindingFlags . InvokeMethod ,
@@ -683,7 +693,7 @@ public static void InvokeMethodVoid(IPythonDerivedType obj, string methodName, s
683693 }
684694
685695 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" ) ;
687697
688698 obj . GetType ( ) . InvokeMember ( origMethodName ,
689699 BindingFlags . InvokeMethod ,
0 commit comments