你能修改一个超类的私有领域吗?

时间:2011-12-19 20:06:29

标签: c# .net oop private encapsulation

我正在使用闭源基类。我可以以某种方式从继承类中更改基类中的私有字段吗?

假设有以下类结构:

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或类似的东西吗?

5 个答案:

答案 0 :(得分: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 :(得分:4)

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

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

其中parentParent的实例。

答案 2 :(得分:2)

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

  1. 如果父类是部分类,您可以定义自己的贡献(另一个父类)来定义公共属性(它可以访问私有字段)。

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

答案 3 :(得分:2)

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

私有字段,属性和方法都是类的合同未明确保证的。如果此第三方API可靠,则他们提供的公共合同不会更改(但他们可以轻松成长)。

从发布到发布,不保证私有和内部部分是相同的。通过将代码与代码的这些部分相结合,您为将来的版本带来了很多风险。如果你对这种风险感到满意(并且已经记录了为什么你这样做了),那么无论如何都要反思。

如果您确实采用了这种方式,我建议您使用所有您的消费代码而不是第三方API的Adapter类。使用适配器模式,只有一个类需要更改以响应第三方API更改。

答案 4 :(得分:1)

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

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