简体   繁体   English

在C#中通过继承向类添加私有方法

[英]Adding private method to class by inheritance in C#

I asked this question yesterday, but I think it was unclear what my primary concern was. 我昨天问过这个问题 ,但我认为目前还不清楚我的主要关注点是什么。 In C++, we have private and multiple inheritance, which enables us to add private methods to classes by just inheriting from the class declaring these methods. 在C ++中,我们有私有和多重继承,这使我们可以通过继承声明这些方法的类来向类添加私有方法。 That is, if there's a class 也就是说,如果有一个班级

class B {
public:
    virtual void doMethodB();
};

and a class 和一个班级

class A : private B {
   virtual int doMethodA();
};

doMethodB() can be called from within doMethodA() , but is not accessible from outside. doMethodB()可以在doMethodA()调用,但不能从外部访问。

Now, I'd like to mimic this behavior in C#. 现在,我想在C#中模仿这种行为。 There is no multiple nor private inheritance. 没有多重或私有继承。 Up to know, I can think of four way to achieve somthing similar, but still with serious drawbacks: 要知道,我可以想到四种方法来实现类似的东西,但仍有严重的缺点:

First: Use an interface , ie 第一:使用interface ,即

interface IB {
    public void doMethodB();
};
class A : IB {
    public void doMethodB();
    int doMethodA();
};

However, when we do this, doMethodB() is public , and must be implemented in each class inheriting from IB . 但是,当我们这样做时, doMethodB()public ,并且必须在从IB继承的每个类中实现。

Second: Use a static method 第二:使用静态方法

public static class B {
    public static void doMethodB();
};

That way, there need only be one implementation, but the method is still public and can't be restricted to certain classes. 这样,只需要一个实现,但该方法仍然是公共的,不能限制在某些类中。

Third: Use a extension method, like that . 第三:使用扩展方法,就像那样 That way however, the method is called on the object (ie a.doMethodB() ) and not from "inside" . 然而,这种方法是对象(即a.doMethodB()调用而不是从“内部”调用。

Fourth: Composition. 第四:组成。

class A {
    private B b;
    public int doMethodA();
};

Now, B 's methods can be called like b.doMethodB() from A only, but are other issues now regarding serialization, b == null etc. 现在, B的方法可以像A b.doMethodB()一样b.doMethodB() ,但现在有关序列化的其他问题, b == null等。

Is there another alternative? 还有另一种选择吗? And if not, which one among the presented ones would you consider "the best" ? 如果没有,你提出的那个中哪一个会被认为是“最好的”

Regarding your "First" proposal with interfaces: you can also implement the interface explicitly: "A class that implements an interface can explicitly implement a member of that interface. When a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface. " See / Source: http://msdn.microsoft.com/en-us/library/aa288461%28v=vs.71%29.aspx 关于带接口的“第一”提议:您还可以显式实现接口:“实现接口的类可以显式实现该接口的成员。当显式实现成员时,不能通过类实例访问它,但是只能通过界面实例。“参见/来源: http//msdn.microsoft.com/en-us/library/aa288461%28v=vs.71%29.aspx

However, i would choose the Composition approach. 但是,我会选择合成方法。 "Favor Composition over Inheritance", also see Prefer composition over inheritance? “赞成组合而不是继承”,还看到Prefer组合而不是继承?

Ideally, i would constructor-inject B into A by dependency injection, that should help mitigate your b == null concern. 理想情况下,我会通过依赖注入将构造函数注入BA ,这应该有助于缓解您的b == null关注点。

Note: Using a static method / extension method (is a static method, too...) makes unit-testing A (respectively faking B ) very hard, which is why i would forgo these solutions completely. 注意:使用静态方法/扩展方法(也是一种静态方法......)使得单元测试A (分别伪造B )非常困难,这就是为什么我会完全放弃这些解决方案。

Edit: If you don't need B.doMethodB accessible from anyone else than A , you can also make B an abstract class and B.doMethodB a protected method. 编辑:如果你不需要除A之外A任何人可以访问B.doMethodB ,你也可以使B成为abstract类, B.doMethodBprotected方法。 But i was thinking that you already know that ;-) (And because of the testing issues i would still favor composition over inheritance). 但我以为你已经知道了;-)(并且由于测试问题,我仍然赞成合成而不是继承)。

I think the concept you are looking for is the protected access modifier. 我认为您正在寻找的概念是protected访问修饰符。 It means that only B itself and its derived classes can access the method, but others cannot. 这意味着只有B本身及其派生类可以访问该方法,但其他人则不能。

class B {
    protected virtual void DoMethodB() {}
}

class A : B {
    virtual void DoMethodA() {
        DoMethodB();
    }
}

If you wanted, you can further restrict the access to protected internal which means that the method can only be accessed from derived classes inside your assembly. 如果需要,可以进一步限制对protected internal的访问,这意味着只能从程序集内的派生类访问该方法。

Also, be aware of the consequences of virtual methods. 另外,请注意虚拟方法的后果。 If there is no explicit need to make a method virtual, it should not be marked virtual. 如果没有明确需要将方法设为虚拟,则不应将其标记为虚拟。

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

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