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

Posted

技术标签:

【中文标题】在派生类中无法访问受保护的成员?【英文标题】:Protected member not accessible in a derived class? 【发布时间】:2016-02-29 16:28:29 【问题描述】:

我有一个基类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.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:

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

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

在我的情况下,有什么建议可以解决这个问题吗? (而不是举办活动public

【问题讨论】:

您为什么不想公开此活动?您是否只希望特定类型能够注册? B 不继承自 A 这就是您无法访问此事件的原因。它们共享相同的基础但不继承。 @YuvalItzchakov 是的,我只想注册 O 派生类。 【参考方案1】:

公开并尝试一下。

这将保证两件事。

首先,关闭事件处理程序附加操作的调用者是从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;
    

【讨论】:

【参考方案2】:

如果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 关键字是成员访问修饰符。受保护的成员可以在其类中访问,也可以通过派生类instances

访问

(强调我的)。

【讨论】:

【参考方案3】:

您将 instanceA 作为类 B 的字段。 Protected 用于在派生类内部访问,而不是在外部访问。所以只有一种解决方案 - 使用 public。

【讨论】:

还有一个解决办法:internal 但它也会使这个事件对程序集中的其他类可见 是的,但正如我所见,Aly 想要隐藏事件,如此公开或内部 - 这并不重要【参考方案4】:

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

这是意料之中的。

受保护的成员可以在其类中访问,也可以通过派生类实例访问。

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

如果您希望这些课程能够看到彼此的成员/事件/等,那么您需要将它们设为公开。

【讨论】:

以上是关于在派生类中无法访问受保护的成员?的主要内容,如果未能解决你的问题,请参考以下文章

C#:基类中的受保护方法;无法使用来自另一个类的派生类对象进行访问[重复]

无法访问派生类中的受保护方法

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

访问派生类中的受保护成员

为啥我不能访问静态多态派生类中的受保护成员?

Java中的间接子类无法访问的超类中的受保护成员