Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
mhsmith opened this issue Jul 11, 2023 · 1 comment
Open

Comments

@mhsmith
Copy link

mhsmith commented Jul 11, 2023

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()))
@mhsmith
Copy link
Author

mhsmith commented Jul 11, 2023

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant