Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inherit from an abstract base class written in C#

I’m trying to inherit from an abstract .NET base class in Python (2.7) using Python.NET (2.1.0). I’m a Python n00b but from what I understood…

Here’s what I managed to do in Python only and which works fine:

import abc

class Door(object):
    __metaclass__ = abc.ABCMeta

    def open(self):
        if not self.is_open():
            self.toggle()

    def close(self):
        if self.is_open():
            self.toggle()

    @abc.abstractmethod
    def is_open(self):
        pass

    @abc.abstractmethod
    def toggle(self):
        pass

class StringDoor(Door):
    def __init__(self):
        self.status = "closed"

    def is_open(self):
        return self.status == "open"

    def toggle(self):
        if self.status == "open":
            self.status = "closed"
        else:
            self.status = "open"

class BooleanDoor(Door):
    def __init__(self):
        self.status = True

    def is_open(self):
        return self.status

    def toggle(self):
        self.status = not (self.status)

Door.register(StringDoor)
Door.register(BooleanDoor)

Now, all I did was to replace the abstract base class Door by a C# representation:

namespace PythonAbstractBaseClass
{
    public abstract class Door
    {
        public virtual void Open()
        {
            if (!IsOpen())
                Toggle();
        }

        public virtual void Close()
        {
            if (IsOpen())
                Toggle();
        }

        public abstract bool IsOpen();
        public abstract void Toggle();
    }
}

Removing Door from the Python part and importing it from the .NET assembly instead, I end up with this:

import clr
import abc
from PythonAbstractBaseClass import Door

class StringDoor(Door):
    def __init__(self):
        self.status = "closed"

    def is_open(self):
        return self.status == "open"

    def toggle(self):
        if self.status == "open":
            self.status = "closed"
        else:
            self.status = "open"

class BooleanDoor(Door):
    def __init__(self):
        self.status = True

    def is_open(self):
        return self.status

    def toggle(self):
        self.status = not (self.status)

Door.register(StringDoor)
Door.register(BooleanDoor)

But this fails with the following error message:

    Door.register(StringDoor)
AttributeError: type object 'Door' has no attribute 'register'

From what I understood about abc.ABCMeta, this metaclass contributes the register() method. It seems that abstract C# classes do not come with the same metaclass. They instead come with metaclass CLR Metatype which obviously does not provide register().

But if I drop the call to register(), on instantiating one of the derived classes, I receive the error message

    sdoor = StringDoor()
TypeError: cannot instantiate abstract class

Is there a way to inherit from an abstract .NET class or is this a missing feature?

Thanks in advance,

Henning

like image 883
freefall Avatar asked Sep 23 '16 11:09

freefall


People also ask

Can you inherit an abstract base class?

NO. Abstract methods(defintion) are overridden by base class' overriding methods.

How do you inherit an abstract class?

Abstract Class If a class is declared abstract, it cannot be instantiated. To use an abstract class, you have to inherit it from another class, provide implementations to the abstract methods in it. If you inherit an abstract class, you have to provide implementations to all the abstract methods in it.

Can I inherit interface in abstract class?

As we all know that an interface can inherit another interface, and interface can only contain method signature. Now the class which implement interface B need to provide body of two functions. So why can't be a interface can inherit a abstract class or a normal class.

Can an abstract class in C plus plus be inherited?

Abstract classes in C++ need to have at least one pure virtual function in a class. The classes that inherit the abstract class must provide a definition for the pure virtual function, else the subclass will itself become an abstract class.


2 Answers

You cannot create a new instance of an abstract class in C#. that said, Python will require you to use the register, as it will not allow you to use your inherited class without registering it, unless you instantiate it.

if you want to inherit from an C# abstract class in python, you will have to write on your own the representation of register class in python at your C# class, thus will register your abstract call and be able to inherit from it.

I would suggest this site to easily help you convert between the codes if need to:

https://www.varycode.com/converter.html

like image 139
Barr J Avatar answered Oct 19 '22 18:10

Barr J


I'm totally not familiar with pythonnet (or python in general for that matter), but I'm curious if something like this might work:

import clr
import abc
from PythonAbstractBaseClass import Door

class DoorWrapper(Door):
    __metaclass__ = abc.ABCMeta

class StringDoor(DoorWrapper):
  ...

class BooleanDoor(DoorWrapper):
  ...

DoorWrapper.register(StringDoor)
DoorWrapper.register(BooleanDoor)
like image 35
martennis Avatar answered Oct 19 '22 18:10

martennis