在派生类中无法访问受保护的成员?
Posted
技术标签:
【中文标题】在派生类中无法访问受保护的成员?【英文标题】:Protected member not accessible in a derived class? 【发布时间】:2016-02-29 16:28:29 【问题描述】:我有一个基类O
,和两个派生类:A : O
和B : 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 关键字是成员访问修饰符。受保护的成员 可在其类内和派生类实例中访问。
但是虽然A
和B
都是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】:如果O
、A
和B
都在同一个程序集中,如果您不想公开,可以使用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】:
但尽管
A
和B
都是O
的派生类,但它们不能使用彼此的基本受保护成员。
这是意料之中的。
受保护的成员可以在其类中访问,也可以通过派生类实例访问。
A
派生自 O
,而不是 B
,因此它无法看到 B
的受保护成员(反之亦然)。
如果您希望这些课程能够看到彼此的成员/事件/等,那么您需要将它们设为公开。
【讨论】:
以上是关于在派生类中无法访问受保护的成员?的主要内容,如果未能解决你的问题,请参考以下文章