繁体   English   中英

受保护的成员无法在派生类中访问?

[英]Protected member not accessible in a derived class?

我有一个基类O和两个派生类: A : OB : O像这样:

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..
    }
}

我想打电话给B.MyMethod(); B.instanceA.ValueChanged引发时,但是当我发现我不能像这样做时,我感到很惊讶:

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..
    }
}

根据MSDN

protected关键字是成员访问修饰符。 受保护的成员可以在其类内以及派生类实例进行访问。

但是,尽管AB都是从O派生的类,但它们不能使用彼此的基保护成员。

有什么建议可以解决这个问题吗? (而不是将活动public

但是,尽管AB都是从O派生的类,但它们不能使用彼此的基保护成员。

这是预料之中的。

受保护的成员可以在其类内以及派生类实例进行访问。

A是从O而不是B派生的,因此它不可能看到B的受保护成员(反之亦然)。

如果希望这些类能够看到彼此的成员/事件/等,则需要将它们公开。

如果OAB都在同一程序集中,则您可以使用internal如果您不希望将其公开。 否则,在这种情况下,您只能使用public访问权限。

当您尝试以这种方式访问​​基类成员时,您仅通过public API而不是protected来访问它。 您可以尝试以下操作,亲自查看:

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

    private O instanceO;
}

这仍然会给出编译错误。 您可以访问B ValueChanged ,但只能通过B的实例访问,如其在引号中所述:

protected关键字是成员访问修饰符。 受保护的成员可以在其类内以及派生的类实例进行访问

(强调我的)。

您具有instanceA作为类B的字段。受保护用于在派生类内部访问,但不能在外部访问。 因此,只有一种解决方案-使用public。

公开并尝试一下。

这将保证两件事。

首先,事件处理程序附加操作的调用者是从O派生的类的成员(或静态)方法,

其次,作为事件处理程序传递的委托是从O派生的类的成员(或静态)方法。

public delegate void ValueChangedEventHandler();

private event ValueChangedEventHandler valueChanged;
public event ValueChangedEventHandler ValueChanged
{
    add
    {
        if (!typeof(O).IsAssignableFrom(value.Method.DeclaringType))
        {
            throw new ArgumentException();
        }
        if (!typeof(O).IsAssignableFrom(new StackTrace().GetFrame(1).GetMethod().DeclaringType))
        {
            throw new ArgumentException();
        }
        valueChanged += value;
    }
    remove
    {
        valueChanged -= value;
    }
}

暂无
暂无

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

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