我从外部库中获得了一个我无法修改的基类 - 这是相关部分:
public class BaseClass
{
List<string> _values;
public Values { get { return _values; } }
}
我继承了BaseClass,我想将_values设置为一个继承自构造函数中List(T)的类:
public InheritingClass : BaseClass
{
public InheritingClass():base()
{
//set base._values = new InhertingList<string>(); ?
}
}
在那里设置base._values的最佳方法是什么?有没有办法找到值获取的私有变量,并设置以防将来重命名私有变量?
我可以通过其他方式完成我需要做的事情,但如果我能做到以下几点,那么在没有设置私有财产价值的情况下,实现目标的方式会更快。
答案 0 :(得分:7)
根据定义,将其保密是为了防止出现这种情况。
最好的选择是实现受保护的setter:
public class BaseClass
{
public Values {
get { return _values; }
protected set { _values = value; }
}
}
这样,您的InheritingClass可以访问setter,并且可以执行:
this.Values = new InhertingList<string>();
但是由于您无法更改基类,从技术上讲,可以通过反射(在完全信任场景中)来实现。不过,我不推荐这种方法:
FieldInfo field = typeof(BaseClass).GetField("_value", BindingFlags.Instance | BindingFlags.NonPublic );
field.SetValue(this, this.Values = new InhertingList<string>() );
你正在尝试做什么的危险,顺便说一下,你要将BaseClass定义的实现改为你提供的东西。引入微妙的错误非常容易,因为你(有目的地)“破坏”基类中的实现细节。
我会尝试重新考虑您的算法,看看是否还有另一种解决此问题的方法。
答案 1 :(得分:2)
如果确实需要设置值,可以使用反射。但这不是很好的编码风格,可能会很慢。
编辑: 有可能反汇编您的BaseClass并更改其实现。然后你可能需要拆开整个库。
也许您可以提供有关问题的更多详细信息?
答案 2 :(得分:1)
通常,当您没有为字段提供可访问setter的属性时,这意味着您不应该从BaseClass以外的任何位置修改该字段 - 如果BaseClass类的创建者希望您成为能够修改该字段,他已经使用受保护的setter或类似的东西暴露了一个属性。所以一般不建议破解它。
你当然可以通过反思来做到这一点,让你知道私人领域的名字 - 我认为不可能提取财产的主体。
至于其他答案:他写道:“我从外部图书馆得到了一个我无法修改的基类”。
答案 3 :(得分:1)
您无法设置私有属性。您将不得不从另一个基类继承或创建自己的基类来提供行为。
当然,根据您的应用程序运行的信任级别,您可以通过反射设置私有变量,但这实际上是一个黑客来解决设计中的实际问题。
答案 4 :(得分:0)
不,没有办法做你想要的。私有变量是私有的 - 即任何代码都无法看到或改变它们。
答案 5 :(得分:0)
通常,当字段没有mutator方法时,您将使用类的构造函数来实例化对象(以及它的相关字段)。
BaseClass base = new BaseClass(List<string> yourList);
答案 6 :(得分:0)
您总是可以使用“new”关键字,但如果将类强制转换回其基础对象,则会忽略继承的方法
public InheritingClass : BaseClass
{
public InheritingClass()
{
Values = new InhertingList<string>(); ?
}
public new List<string> Values { get; private set; }
}
要访问私有字段,您可以使用Reflection,但由于该字段是私有的,我不确定继承类如何从更改私有字段类型中受益。
public InheritingClass : BaseClass
{
private static FieldInfo _valueField = typeof(BaseClass).GetField("_values", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
public InheritingClass()
{
_valueField.SetValue(this, new InhertingList<string>());
}
}
http://msdn.microsoft.com/en-us/library/6z33zd7h(v=vs.110).aspx