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

Protected member not accessible in a derived class?

我有一个基础 class O 和两个派生的 classes: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.instanceA.ValueChanged 被引发时调用 B.MyMethod();,但是当我发现我不能这样做时,我很惊讶:

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

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

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

有什么建议可以解决我的问题吗? (而不是让事件 public

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

这是意料之中的事情。

A protected member is accessible within its class and by derived class instances.

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

如果您希望这些 类 能够看到彼此的 members/events/etc,那么您需要将它们设置为 public。

如果 OAB 都在同一个程序集中,您可以使用 internal 如果您不希望它是 public.否则,在这种情况下您只能 public 访问。

当您尝试以这种方式访问​​基本 class 成员时,您只能通过 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 的实例访问,正如引用中所说:

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

(强调我的)。

您将 instanceA 作为 classB 的字段。Protected 用于在派生 class 内部访问,但不能在外部访问。所以只有一种解决方案——使用 public.

制作 public 并尝试这个。

这将保证两件事。

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

其次,作为事件处理程序传递的委托是从 O.

派生的 class 的成员(或静态)方法
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;
    }
}