using 语句中的成员范围
Scope of members inside using statement
我对以下代码和 using 语句的范围及其对象处理感到困惑。
using(DbFactory db = new DbFactory())
{
Repository repo = new Repository<someobject>(db);
result = repo.Get(somecondition);
}
在这段代码中,执行 using 块后会发生什么 DbFactory
会被处置?
using 语句中使用的 repo
变量的范围是什么?
DbFactory
由 Repository
使用,它有一个成员变量将保存 DbFactory
。
那么这会保留 DbFactory
的处理吗?
编辑1:
Repository repo;
ResultObject result;
using(DbFactory db = new DbFactory())
{
repo = new Repository<someobject>(db);
result = repo.Get(somecondition);
}
public class Repository
{
private _dbFactory;
public Repository(DbFactory dbFactory)
{
_dbFactory = dbFactory;
}
}
现在 DbFactory 会在 using 语句后被释放吗?
will the DbFactory gets disposed?
是的。
What will be the scope of repo variable used inside the using statement?
repo
的范围是它所在的块,所以它包裹的那对花括号('{','}')。在这种情况下,它恰好重合在您的 using
声明正文中,是的。
repo
变量的范围(在您的第一种情况下)是 using
语句。您不能在 using
语句之外引用它,因为它已在其中声明。
我们无法判断 result
变量的范围,因为您没有显示它的声明,但它至少是 "bigger than the using
statement".
更有趣的是result
的值所指的对象在DbFactory
被释放后的可用性如何。那是 implementation-specific,基本上......我希望如果访问任何 result
属性需要进一步的数据库查询(例如获取外键引用的对象)那么它会失败,但是任何已经获取的东西应该没问题。
至于销毁的时间——DbFactory
将在 using
语句结束时销毁。这与垃圾收集完全分开,并且 Repository
对象可能仍然有对它的引用——但在工厂被处理后它可能就没用了。因此,如果您在 using
语句后调用 repo.Get(...)
,您可能会看到一个异常,这取决于该代码实际对工厂做了什么,以及如何处置工厂的行为。同样,处置不是垃圾收集。它只是调用 Dispose
方法 - CLR 不会以任何特殊方式关心它。
如果回购也是一次性的,您可能也想处理它,例如:
using(DbFactory db = new DbFactory())
using(Repository repo = new Repository<someobject>(db))
{
result = repo.Get(somecondition);
}
这个:
Repository repo;
ResultObject result;
using(DbFactory db = new DbFactory())
{
repo = new Repository<someobject>(db);
result = repo.Get(somecondition);
}
与这个相同:
Repository repo;
ResultObject result;
{
DbFactory db = new DbFactory()
repo = new Repository<someobject>(db);
result = repo.Get(somecondition);
db.Dispose();
}
因此,尽管 db 对象本身不会消失(对它的引用将保留在 Repository 实例中,但它将处于 Disposed/Closed 状态。取决于 DbFactory 的实现,这可能会破坏您的代码。
您没有提供完整的代码以及它应该做什么,但我认为您应该朝这个方向前进:
在您的 Repository 对象中实现 IDisposable,并在其中处理 DbFactory:
public class Repository : IDisposable
{
private _dbFactory;
public Repository(DbFactory dbFactory)
{
_dbFactory = dbFactory;
}
public void Dispose()
{
_dbFactory.Dispose();
}
}
现在这样使用:
ResultObject result;
using (Repository repo = new Repository(new DbFactory())
{
result = repo.Get(somecondition);
}
或嵌套使用:
using (DbFactory db = new DbFactory())
{
using(Repository repo = new Repository(db))
{
result = repo.Get(somecondition);
}
}
我对以下代码和 using 语句的范围及其对象处理感到困惑。
using(DbFactory db = new DbFactory())
{
Repository repo = new Repository<someobject>(db);
result = repo.Get(somecondition);
}
在这段代码中,执行 using 块后会发生什么 DbFactory
会被处置?
using 语句中使用的 repo
变量的范围是什么?
DbFactory
由 Repository
使用,它有一个成员变量将保存 DbFactory
。
那么这会保留 DbFactory
的处理吗?
编辑1:
Repository repo;
ResultObject result;
using(DbFactory db = new DbFactory())
{
repo = new Repository<someobject>(db);
result = repo.Get(somecondition);
}
public class Repository
{
private _dbFactory;
public Repository(DbFactory dbFactory)
{
_dbFactory = dbFactory;
}
}
现在 DbFactory 会在 using 语句后被释放吗?
will the DbFactory gets disposed?
是的。
What will be the scope of repo variable used inside the using statement?
repo
的范围是它所在的块,所以它包裹的那对花括号('{','}')。在这种情况下,它恰好重合在您的 using
声明正文中,是的。
repo
变量的范围(在您的第一种情况下)是 using
语句。您不能在 using
语句之外引用它,因为它已在其中声明。
我们无法判断 result
变量的范围,因为您没有显示它的声明,但它至少是 "bigger than the using
statement".
更有趣的是result
的值所指的对象在DbFactory
被释放后的可用性如何。那是 implementation-specific,基本上......我希望如果访问任何 result
属性需要进一步的数据库查询(例如获取外键引用的对象)那么它会失败,但是任何已经获取的东西应该没问题。
至于销毁的时间——DbFactory
将在 using
语句结束时销毁。这与垃圾收集完全分开,并且 Repository
对象可能仍然有对它的引用——但在工厂被处理后它可能就没用了。因此,如果您在 using
语句后调用 repo.Get(...)
,您可能会看到一个异常,这取决于该代码实际对工厂做了什么,以及如何处置工厂的行为。同样,处置不是垃圾收集。它只是调用 Dispose
方法 - CLR 不会以任何特殊方式关心它。
如果回购也是一次性的,您可能也想处理它,例如:
using(DbFactory db = new DbFactory())
using(Repository repo = new Repository<someobject>(db))
{
result = repo.Get(somecondition);
}
这个:
Repository repo;
ResultObject result;
using(DbFactory db = new DbFactory())
{
repo = new Repository<someobject>(db);
result = repo.Get(somecondition);
}
与这个相同:
Repository repo;
ResultObject result;
{
DbFactory db = new DbFactory()
repo = new Repository<someobject>(db);
result = repo.Get(somecondition);
db.Dispose();
}
因此,尽管 db 对象本身不会消失(对它的引用将保留在 Repository 实例中,但它将处于 Disposed/Closed 状态。取决于 DbFactory 的实现,这可能会破坏您的代码。
您没有提供完整的代码以及它应该做什么,但我认为您应该朝这个方向前进:
在您的 Repository 对象中实现 IDisposable,并在其中处理 DbFactory:
public class Repository : IDisposable { private _dbFactory; public Repository(DbFactory dbFactory) { _dbFactory = dbFactory; } public void Dispose() { _dbFactory.Dispose(); } }
现在这样使用:
ResultObject result; using (Repository repo = new Repository(new DbFactory()) { result = repo.Get(somecondition); }
或嵌套使用:
using (DbFactory db = new DbFactory())
{
using(Repository repo = new Repository(db))
{
result = repo.Get(somecondition);
}
}