我有一个与数据库无关的游标操作的抽象类。从中派生出一些类,它们实现了用于处理特定于数据库的东西的抽象方法。
问题是,基类ctor需要调用一个抽象方法——当调用ctor时,它需要初始化数据库特定的游标。
我知道为什么不应该这样做,我不需要那个解释!
这是我的第一个实现,显然不起作用 - 这是教科书的“错误方式”。重写的方法访问派生类中的一个字段,该字段尚未实例化:
public abstract class CursorReader
{
private readonly int m_rowCount;
protected CursorReader(string sqlCmd)
{
m_rowCount = CreateCursor(sqlCmd); //virtual call !
}
protected abstract int CreateCursor(string sqlCmd);
//...other (non-abstract) methods that assume a cursor exists
}
public class SqlCursorReader : CursorReader
{
private SqlConnection m_sqlConnection;
public SqlCursorReader(string sqlCmd, SqlConnection sqlConnection)
{
m_sqlConnection = sqlConnection; //field initialized here
}
protected override int CreateCursor(string sqlCmd)
{
//uses not-yet-initialized member *m_sqlConnection*
//so this throws a NullReferenceException
var cursor = new SqlCursor(sqlCmd, m_sqlConnection);
cursor.Create();
return cursor.Count();
}
}
我将跟进我尝试解决此问题的答案...
更新
重写的方法在数据库中CreateCursor()
创建一个实际的游标。这对于类中省略的许多方法的正确运行至关重要。
CreateCursor()
必须在基 ctor 中调用,以便类在 ctor 返回时处于一致状态。我稍微更新了上面的代码以反映这一点。