我有一个基类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
)
答案 0 :(得分:1)
但是,虽然
A
和B
都是来自O
的派生类,但他们无法使用彼此的基本受保护成员。
这是可以预期的。
受保护的成员可以在其类和派生类实例中访问。
A
源自O
,而不是B
,因此无法看到B
的受保护成员(反之亦然)。
如果您希望这些课程能够看到彼此的成员/活动/等,那么您需要将它们公之于众。
答案 1 :(得分:1)
如果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;
}
这仍然会出现编译错误。您可以访问ValueChanged
中的B
,但只能访问B
的实例,如引号中所述:
protected关键字是成员访问修饰符。受保护的成员可在其类中以及派生类实例
中访问
(强调我的)。
答案 2 :(得分:0)
您将instanceA作为B类的字段.Protected用于在派生类内部访问,但不在外部访问。因此,只有一种解决方案 - 使用公共。
答案 3 :(得分:0)
公开并试试。
这将保证两件事。
首先,关闭事件处理程序附加操作的调用者是从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;
}
}