我有一个类,它有一个方法可以调用隐藏在继承它的类中的对象上的方法(但是新字段也是从baseField继承而来的),我需要调用此方法。新字段,但当我调用childClass.doSomething()时,我得到一个异常,说baseField为null。
我认为这是因为正在访问baseClass中的baseField,它还没有被实例化,但我不确定
从childClass
访问时,如何让someMethod使用ExtendedBaseFieldpublic abstract class baseClass{
protected BaseField baseField;
public void someMethod(){
baseField.doSomething()
}
}
继承它的类:
public class childClass : baseClass{
protected new ExtendedBaseField baseField = new ExtendedBaseField();
}
new childClass().someMethod(); //null pointer exception
ExtendedBaseField继承BaseField
答案 0 :(得分:1)
您正在使用新关键字创建新字段,而不是设置旧字段。我反对保护田地,它们应该是财产。你也应该了解.NET中的所有属性,方法和类。括号也应该自行排列。
根据您的意见,您希望对新类型进行类型化访问,因此您应该使基类具有通用性。我也证明了这一点。
public abstract class BaseClass<T>
where T: BaseField
{
protected BaseClass(T baseField)
{
this.BaseField = baseField;
}
protected T BaseField{get; private set;};
public void SomeMethod()
{
BaseField.DoSomething()
}
}
public class ChildClass : BaseClass<ExtendedBaseField>
{
public ChildClass() : base(new ExtendedBaseField())
{
}
}
答案 1 :(得分:1)
其他人给出了正确的技术答案:您明确地将该字段隐藏在基类中。
我会在这里说出不好的做法。
在C ++中,有RAII的概念。资源分配是初始化。在C#中,我们通常不必像在C ++中那样考虑资源分配,但RAII的模式仍然是一种很好的做法。
类中声明的所有字段都应该内联初始化
protected BaseField baseField = new BaseField();
...或在该类的构造函数中
protected BaseField baseField;
public BaseClass<T>()
{
this.baseField = new BaseField();
}
如果不可能,那么使用抽象属性而不是字段,这会强制子类实现并初始化它。
protected abstract BaseField BaseField { get; }
答案 2 :(得分:0)
子类隐藏 baseField
:
protected new ExtendedBaseField baseField = new ExtendedBaseField();
这会创建一个new
baseField
属性,因此子类无法再看到基类“baseField
属性。因此,它从未设定。因此,它是null
。
不要隐藏基类'字段。如果希望基类使用它,请让子类使用它来:
public class childClass : baseClass {
public childClass() {
baseField = new ExtendedBaseField();
}
}