[英]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.