简体   繁体   English

如何从用C#编写的抽象基类继承

[英]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). 我试图使用Python.NET(2.1.0)继承Python(2.7)中的抽象.NET基类。 I'm a Python n00b but from what I understood… 我是Python n00b,但据我所知...

Here's what I managed to do in Python only and which works fine: 这是我在Python中设法做的事情,并且工作正常:

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: 现在,我所做的只是用C#表示替换抽象基类Door:

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: 从Python部件中删除Door并从.NET程序集中导入它,我最终得到:

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. 根据我对abc.ABCMeta理解,这个元类贡献了register()方法。 It seems that abstract C# classes do not come with the same metaclass. 似乎抽象的C#类没有相同的元类。 They instead come with metaclass CLR Metatype which obviously does not provide register() . 他们改为使用元类CLR Metatype ,它显然不提供register()

But if I drop the call to register() , on instantiating one of the derived classes, I receive the error message 但是如果我将调用放到register() ,在实例化一个派生类时,我会收到错误消息

    sdoor = StringDoor()
TypeError: cannot instantiate abstract class

Is there a way to inherit from an abstract .NET class or is this a missing feature? 有没有办法从抽象的.NET类继承或者这是一个缺少的功能?

Thanks in advance, 提前致谢,

Henning 亨宁

You cannot create a new instance of an abstract class in C#. 您无法在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. 也就是说,Python会要求你使用寄存器,因为它不允许你使用你继承的类而不注册它,除非你实例化它。

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. 如果你想继承python中的C#抽象类,你必须在C#类中自己编写python中寄存器类的表示,这样就会注册你的抽象调用并能够继承它。

I would suggest this site to easily help you convert between the codes if need to: 如果需要,我建议这个网站可以轻松帮助您在代码之间进行转换:

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

I'm totally not familiar with pythonnet (or python in general for that matter), but I'm curious if something like this might work: 我对pythonnet(或者一般的python)完全不熟悉,但我很好奇这样的事情是否可行:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM