gpt4 book ai didi

构造函数中的 C# 虚拟方法调用 - 如何重构?

转载 作者:行者123 更新时间:2023-11-30 14:14:10 27 4
gpt4 key购买 nike

我有一个抽象类,用于与数据库无关的游标操作。从那里派生出,有一些类实现了处理特定于数据库的东西的抽象方法。

问题是,基类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 返回时处于一致状态。我稍微更新了上面的代码以反射(reflect)这一点。

最佳答案

你总是可以有一个惰性属性来获取计数。

public abstract class CursorReader
{
private int? m_rowCount;
protected CursorReader()
{

}
protected abstract int CreateCursor(string sqlCmd);
protected int RowCount {
get {
if (m_RowCount == null)
{
m_RowCount = CreateCursor(sql);
}
return m_RowCount.Value;
}

}
}

关于构造函数中的 C# 虚拟方法调用 - 如何重构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12711752/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com