C# override public member and make it private

2019-02-08 16:14发布

问题:

Possible? Can you change the access of anything to anything else?

回答1:

No, you can hide a public member with a private method in a subclass, but you cannot override a public member with a private one in a subclass. And, in actually, it's not just a public/private thing, this applies to narrowing the access in general.

Revised: By hiding with a more restrictive access - in this case private access - you will still see the base class member from a base-class or sub-class reference, but it would defer to the new method when available from the new access level.

So in general, when you hide, the hide takes precedence when visible at its access level. Otherwise the original method is the one used.

public class BaseClass
{
    public virtual void A() { }

    public virtual void B() { }
}

public class SubClass
{
    // COMPILER ERROR, can't override to be more restrictive access
    private override void A() { }

    // LEGAL, you can HIDE the base class method, but which is chosen 
    // depends on level accessed from
    private new void B() { }
}

So SubClass.B() ONLY hides the base class methods when it is accessible. That is, if you call SubClass.B() inside of SubClass then it will take the hidden form of B(), but since B() is private, it is not visible to classes outside of itself, and thus they STILL see BaseClass.B().

The long and the short of it is:

1) You cannot override a method to be more restrictive (access wise). 2) You can hide a method with a more restrictive one, but it will only have an effect where that new access type is visible, otherwise the base one stands.

public class BaseClass
{
    public virtual void A() { }
    public virtual void B() { }
}

public class SubClass : BaseClass
{
    public virtual void A() { B(); }

    // legal, you can do this and B() is now hidden internally in SubClass,
    // but to outside world BaseClass's B() is still the one used.
    private new void B() { }
}

// ...

SubClass sc = new SubClass();
BaseClass bc = new BaseClass();

// both of these call BaseClass.B() because we are outside of class and can't
// see the hide SubClass.B().
sc.B();
bc.B();

// this calls SubClass.A(), which WILL call SubClass.B() because the hide
// SubClass.B() is visible within SubClass, and thus the hide hides BaseClass.B()
// for any calls inside of SubClass.
sc.A();


回答2:

Nope.

A typical way to deal with this is to throw a NotImplementedException or something to that effect.



回答3:

You cannot narrow or widen the visibility of an overriden member. However, you can define another method with the new keyword, which can give you a new method with the same name, but which is incompatible in terms of polymorphism.

public class A : B
{
    public new void Foo()
    {
        base.Foo();
    }
}