[英]Protected member not accessible in a derived class?
我有一个基类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.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关键字是成员访问修饰符。 受保护的成员可以在其类内以及派生类实例进行访问。
但是,尽管A
和B
都是从O
派生的类,但它们不能使用彼此的基保护成员。
有什么建议可以解决这个问题吗? (而不是将活动public
)
但是,尽管
A
和B
都是从O
派生的类,但它们不能使用彼此的基保护成员。
这是预料之中的。
受保护的成员可以在其类内以及派生类实例进行访问。
A
是从O
而不是B
派生的,因此它不可能看到B
的受保护成员(反之亦然)。
如果希望这些类能够看到彼此的成员/事件/等,则需要将它们公开。
如果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关键字是成员访问修饰符。 受保护的成员可以在其类内以及派生的类实例进行访问
(强调我的)。
您具有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.