2011-12-19 59 views
1

我正在使用一个封闭源代码基类。我可以以某种方式从我的继承类中更改基类中的私有字段吗?你可以修改超类的私人领域吗?

假设下面的类结构:

public class Parent 
{ 
    private bool age; 
} 

public class Baby : Parent 
{ 
    public bool newAge{ 
     get { 
      return age; 
     } 
    } 
} 

目前这给你一个编译时错误:

'Parent.age' is inaccessible due to its protection level. 

如何从婴儿类访问现场“年龄”?你能使用reflection或类似的东西吗?

+0

父类是普通类还是部分类? – everton 2011-12-19 20:14:52

+0

父类是一个抽象类。 – 2011-12-19 20:42:50

+5

如果基类的作者希望你能够做到这一点,那么他们会让这个领域受到保护。很明显,他们不*希望你这样做,所以不要这样做。如果你想添加这个功能,**放入一个功能请求**。不要做出危险脆弱的代码,依赖于实现细节,类的作者故意阻止你依赖*。 – 2011-12-19 20:54:41

回答

5

您可以使用反射。它看起来像这样:

public class Baby : Parent 
{ 
    private readonly FieldInfo _ageField = typeof(Parent).GetField("age", BindingFlags.NonPublic | BindingFlags.Instance); 
    public int newAge 
    { 
     get 
     { 
      return (int)_ageField.GetValue(this); 
     } 
     set 
     { 
      _ageField.SetValue(this, value); 
     } 
    } 
} 

如果它是由第三方提供,没有任何更改它,给它改名阻止他们,就清除它一起。这是private的其中一点。请记住,它可能是私人的原因。修补你不认为会导致意想不到的结果的地方。

+1

最后一句话+1。 – 2011-12-19 20:15:48

4

您可以尝试使用反射来访问专用字段并对其进行修改。像:

typeof(Parent) 
.GetField("age", BindingFlags.Instance | BindingFlags.NonPublic) 
.SetValue(parent, 14); 

其中parentParent一个实例。

+3

+1,但值得考虑的是,在任何现实世界的代码中,人们必须小心谨慎,因为它可以将对象置于不期望的状态,并导致很难追踪的错误。 – 2011-12-19 20:15:20

2

好吧,既然你不能改变父类的源代码,有可能是2种选择:

  1. 如果父类是局部类,你可以定义自己的贡献(其它父类)定义一个公共财产(它可以访问私人领域)。

  2. 你确实可以使用反射。

+4

他不能:'闭源基类' – vcsjones 2011-12-19 20:09:07

+0

下决心,我的道歉,我还没有看到问题中的第一个陈述。我提供了另一种选择,所以请重新考虑投票。 – everton 2011-12-19 20:20:31

+1

只有当他有父类的来源时,部分类才会有用,我可能会建议首先将该字段更改为受保护的。记住一个分类是一个编译器功能,运行时完全不知道它。 – vcsjones 2011-12-19 20:22:41

1

不,你不能这样做。除非您使用反射,例如:

Reflection.FieldInfo fields[] = 
    myType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance); 
2

可以通过反射修改这些值。话虽如此,你可能不应该。

私人领域,属性和方法都是没有明确保证的类的合同。如果这个第三方API是可靠的,他们提供的公共合同不会改变(但他们可以很容易地增长)。

从发布到发布,私人和内部零件不保证是相同的。通过将您的代码与代码的这些部分结合起来,您为未来版本引入了很大的风险。如果你对这种风险确定(并且有关你为什么这样做的详细记录),那么通过一切手段就可以反映出来。

如果你确实走这条路线,我会推荐一个适配器类,所有你的消费代码使用,而不是这个第三方API。使用适配器模式,只有一个类需要更改以响应第三方API更改。