Search code examples
c#oopevent-handlingprotectedaccess-modifiers

Protected member not accessible in a derived class?


I have a base class O, and two derived classes: A : O, and B : O like this:

public abstract class O
{
    public O(string val)
    {
        this.Value = val;
    }

    private string value;
    public string Value
    {
        get { return this.value; }
        set
        {
            this.value = value;
            RaiseValueChanged();
        }
    }

    protected delegate void ValueChangedEventHandler();
    protected event ValueChangedEventHandler ValueChanged;
    protected void RaiseValueChanged()
    { if (ValueChanged != null) ValueChanged(); }
}

public sealed class A : O
{
    public A(string val)
        : base(val) { }
}

public sealed class B : O
{
    public B(string val, A instance)
        : base(val)
    {
        instanceA = instance;
    }

    private A instanceA;
    public A InstanceA
    {
        get { return instanceA; }
        set
        {
            instanceA = value;
        }
    }

    public void MyMethod()
    {
        //Some stuff..
    }
}

I want to call B.MyMethod(); when B.instanceA.ValueChanged is raised, but I was surprised when I found out that I can't just do it like this:

public sealed class B : O
{
    public B(string val, A instance)
        : base(val)
    {
        instanceA = instance;
        //instanceA.ValueChanged += MyMethod;
    }

    private A instanceA;
    public A InstanceA
    {
        get { return instanceA; }
        set
        {
            //instanceA.ValueChanged -= MyMethod;
            instanceA = value;
            //instanceA.ValueChanged += MyMethod;
        }
    }

    public void MyMethod()
    {
        //Some stuff..
    }
}

According to MSDN:

The protected keyword is a member access modifier. A protected member is accessible within its class and by derived class instances.

But although both A, and B were derived classes from O, they couldn't use each other's base protected members.

Any suggestions to get around this in my case? (instead of making the event public)


Solution

  • If O, A and B are all in the same assembly, you could use internal if you don't want it to be public. Otherwise you are limited to public access in this case.

    When you try to access a base class member in this way, you are accessing it via the public API only, not via protected. You can see this for yourself by trying the following:

    public sealed class B : O
    {
        public B(string val, O instance)
            : base(val)
        {
            instanceO = instance;
            instanceO.ValueChanged += MyMethod;
        }
    
        private O instanceO;
    }
    

    This still gives a compilation error. You can access ValueChanged in B, but only via an instance of B, as it says in the quote:

    The protected keyword is a member access modifier. A protected member is accessible within its class and by derived class instances

    (emphasis mine).