簡體   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