有没有办法从派生类型到达另一个对象的`protected`成员?

class MyBase { protected object PropertyOfBase { get; set; } } class MyType : MyBase { void MyMethod(MyBase parameter) { // I am looking for: object p = parameter.PropertyOfBase; // error CS1540: Cannot access protected member 'MyBase.PropertyOfBase' via a qualifier of type 'MyBase'; the qualifier must be of type 'MyType' (or derived from it) } } 

有没有办法从没有reflection的扩展类型获取类型参数的受保护属性? 由于扩展类通过其基类型知道属性,因此如果可能的话就有意义。

不,你不能这样做。

您只能访问访问类型(或从中派生)的对象的受保护成员。 在这里,我们不知道参数是MyType类型还是SomeOtherCompletelyDifferentType类型。

编辑:C#3.0规范的相关部分是第3.5.3节:

当在声明它的类的程序文本之外访问受保护的实例成员时,并且在声明它的程序的程序文本之外访问受保护的内部实例成员时,访问必须在类中进行声明派生自声明它的类。 此外,访问需要通过该派生类类型的实例或从其构造的类类型进行。 此限制可防止一个派生类访问其他派生类的受保护成员,即使这些成员是从同一基类inheritance的。

上次我遇到类似问题时,我使用了向基础添加受保护静态方法的解决方案:

 class MyBase { protected object PropertyOfBase { get; set; } protected static object GetPropertyOfBaseOf(MyBase obj) { return obj.PropertyOfBase; } } class MyType : MyBase { void MyMethod(MyBase parameter) { object p = GetPropertyOfBaseOf(parameter); } } 

有一个很好的理由你不能这样做。 假设某人写道:

 class Other : MyBase { } new MyType().MyMethod(new Other()); 

如果语言允许您要求的内容,则可以通过修改PropertyOfBase的值来违反Other假设的不变量。

我想你应该问问自己是否有更好的方法去做你想做的事情。 您希望PropertyOfBase在MyType.MyMethod()的上下文中充当公共,但要在所有其他情况下受到保护。 为什么?

受保护的属性只能由派生类的实例访问,而不能访问派生类的实例。

存在差异并且确实有意义,受保护的成员不应该将其值放弃到任何其他实例,甚至是从相同类型派生的实例。

(编辑,让自己有点舌头!)

当您从MyBaseinheritance时,您可以使用“base”关键字访问标记为“protected”的所有字段/属性/方法。

 public class MyBase { protected object PropertyOfBase { get; set; } } public class MyType : MyBase { void MyMethod() { object p = base.PropertyOfBase; } } 

您还可以将MyType声明为MyBase的嵌套类(而不是inheritance),这样您可以在将MyBase类作为参数发送时访问私有/受保护成员

 public class MyBase { protected object PropertyOfBase { get; set; } public class MyType { public void MyMethod(MyBase parameter) { object p = parameter.PropertyOfBase; } } } 

要创建MyType实例,只需使用

 var t = new MyBase.MyType(); t.MyMethod(new MyBase());