在派生 class 中无法访问受保护成员?
Protected member not accessible in a derived class?
我有一个基础 class O
和两个派生的 classes: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:
The protected keyword is a member access modifier. A protected member
is accessible within its class and by derived class instances.
但是尽管 A
和 B
都是从 O
派生的 classes,它们不能使用彼此的基保护成员。
有什么建议可以解决我的问题吗? (而不是让事件 public
)
But although both A
, and B
were derived classes from O
, they couldn't use each other's base protected members.
这是意料之中的事情。
A protected member is accessible within its class and by derived class instances.
A
派生自 O
,而不是 B
,因此它无法看到 B
的受保护成员(反之亦然)。
如果您希望这些 类 能够看到彼此的 members/events/etc,那么您需要将它们设置为 public。
如果 O
、A
和 B
都在同一个程序集中,您可以使用 internal
如果您不希望它是 public.否则,在这种情况下您只能 public
访问。
当您尝试以这种方式访问基本 class 成员时,您只能通过 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
的实例访问,正如引用中所说:
The protected keyword is a member access modifier. A protected member is accessible within its class and by derived class instances
(强调我的)。
您将 instanceA 作为 classB 的字段。Protected 用于在派生 class 内部访问,但不能在外部访问。所以只有一种解决方案——使用 public.
制作 public 并尝试这个。
这将保证两件事。
首先,关闭事件处理程序附加操作的调用者是从 O 派生的 class 的成员(或静态)方法,
其次,作为事件处理程序传递的委托是从 O.
派生的 class 的成员(或静态)方法
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;
}
}
我有一个基础 class O
和两个派生的 classes: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:
The protected keyword is a member access modifier. A protected member is accessible within its class and by derived class instances.
但是尽管 A
和 B
都是从 O
派生的 classes,它们不能使用彼此的基保护成员。
有什么建议可以解决我的问题吗? (而不是让事件 public
)
But although both
A
, andB
were derived classes fromO
, they couldn't use each other's base protected members.
这是意料之中的事情。
A protected member is accessible within its class and by derived class instances.
A
派生自 O
,而不是 B
,因此它无法看到 B
的受保护成员(反之亦然)。
如果您希望这些 类 能够看到彼此的 members/events/etc,那么您需要将它们设置为 public。
如果 O
、A
和 B
都在同一个程序集中,您可以使用 internal
如果您不希望它是 public.否则,在这种情况下您只能 public
访问。
当您尝试以这种方式访问基本 class 成员时,您只能通过 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
的实例访问,正如引用中所说:
The protected keyword is a member access modifier. A protected member is accessible within its class and by derived class instances
(强调我的)。
您将 instanceA 作为 classB 的字段。Protected 用于在派生 class 内部访问,但不能在外部访问。所以只有一种解决方案——使用 public.
制作 public 并尝试这个。
这将保证两件事。
首先,关闭事件处理程序附加操作的调用者是从 O 派生的 class 的成员(或静态)方法,
其次,作为事件处理程序传递的委托是从 O.
派生的 class 的成员(或静态)方法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;
}
}