← 输入框|github.com|刷新
Skip to content

Support overriding protected virtual methods of a .NET class in Python #2192

Open

Description

@mhsmith

Based on https://stackoverflow.com/questions/75514392 by IkeStarnes.

Environment

  • Pythonnet version: 3.0.1
  • Python version: 3.10 64-bit
  • Operating System: Windows 11
  • .NET Runtime: 6.0

Details

Given the following C# code for the .NET class:

namespace MyTestLib
{
   public class MyTestClass
   {
      private int _x;
      public MyTestClass(int inNumber) { SetNumber(inNumber); }

      public int GetNumber()
      {
         Console.WriteLine(string.Format(".NET MyTestClass.GetNumber: {0}", _x));
         return _x;
      }
      public void SetNumber(int inNumber)
      {
         _x = inNumber;
         Console.WriteLine(string.Format(".NET MyTestClass.SetNumber: {0}", _x));
      }

      protected virtual void OnUseNumber(int inNumber) { }

      public void UseNumber(int inNumber)
      {
         Console.WriteLine(string.Format(".NET MyTestClass.UseNumber: {0}", inNumber));
         OnUseNumber(inNumber);
      }
   }

   public class MyTestClass2 : MyTestClass
   {
      MyTestClass2() : base(55) { }
      protected override void OnUseNumber(int inNumber)
      {
         SetNumber(inNumber * 4000);
         Console.WriteLine(string.Format("MyTestClass2.OnUseNumber: {0}", GetNumber()));
      }
   }
}

I've tried the following Python code, but the OnUseNumber is never called:

class MySubClass(MyTestLib.MyTestClass):
   def __init__(self):
      super().__init__(99)

   def OnUseNumber(self, inNumber):
      self.SetNumber(inNumber * 4000)
      print ("Python MySubClass.OnUseNumber: {}".format(self.GetNumber()))

main():
   myclass = MyTestLib.MyTestClass(10)
   print("Before use: {}".format(myclass.GetNumber()))
   myclass.UseNumber(5)
   print("After use: {}".format(myclass.GetNumber()))

   myclass2 = MyTestLib.MyTestClass2()
   print("Before use: {}".format(myclass2.GetNumber()))
   myclass2.UseNumber(5)
   print("After use: {}".format(myclass2.GetNumber()))

   mysubclass = MySubClass()
   print("Before use: {}".format(mysubclass.GetNumber()))
   mysubclass.UseNumber(5)
   print("After use: {}".format(mysubclass.GetNumber()))

Activity

  1. mhsmith commented on Jul 11, 2023

    @mhsmith
    Author

    If OnUseNumber was public virtual, then this could probably be fixed by adding a __namespace__ attribute to the Python class, as in #567 (comment).

    However, based on this discussion, overriding protected virtual methods is not currently supported. I think this is because of the use of the zero-argument form of GetMethods here, which only returns public methods.

    This particularly affects Winforms, which has a lot of protected virtual methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions