使用声明中的成员范围

时间:2017-01-25 17:58:31

标签: c# using-statement

我对以下代码以及using语句及其对象处理的范围感到困惑。

using(DbFactory db = new DbFactory())
{
   Repository repo = new Repository<someobject>(db);
   result = repo.Get(somecondition);
}

在此代码中,使用块执行后会发生什么DbFactory被处理? 在using语句中使用的repo变量的范围是什么? DbFactory使用Repository,它有一个成员变量,用于保存DbFactory。 那么这会占用DbFactory吗?

EDIT1:

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语句之后被释放吗?

4 个答案:

答案 0 :(得分:8)

repo变量的范围(在第一种情况下)是using语句。您无法在using声明之外引用它,因为它已在那里声明。

我们无法告知result变量的范围,因为您尚未显示其声明,但它至少比{{1}更大声明&#34;。

更有意思的是,using的值所引用的对象在result被处置之后的可用性。这是特定于实现的,基本上......我希望如果访问任何DbFactory属性需要进一步的数据库查询(例如,获取外键引用的对象)那么它会失败,但是任何已经取得的东西应该没问题。

至于处置时间 - result将在DbFactory声明的末尾处理。这与垃圾收集完全分开,并且可能using对象仍然会引用它 - 但在工厂处置后它可能没用。因此,如果您在 Repository语句之后调用repo.Get(...) ,您可能会看到异常,具体取决于该代码实际对工厂执行的操作以及处置方式工厂表现。同样,处置不是垃圾收集。它只是调用using方法 - CLR并不以任何特殊的方式关注它。

答案 1 :(得分:3)

  

DbFactory会被处理掉吗?

  

using语句中使用的repo变量的范围是什么?

O(nlogm)的范围是它所包含的块,所以它所包含的花括号('{','}')对。在这种情况下,它碰巧与repo陈述的正文,是的。

答案 2 :(得分:0)

如果回购也是一次性的,您也可以将其丢弃,例如:

using(DbFactory db = new DbFactory())
using(Repository repo = new Repository<someobject>(db))
{
   result = repo.Get(somecondition);
}

答案 3 :(得分:0)

此:

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的实现可能会破坏你的代码。

你没有提供完整的代码以及它应该做什么,但我认为你应该朝着这个方向前进:

  1. 在您的Repository对象中实现IDisposable,并在其中部署DbFactory:

    public class Repository : IDisposable
    {
        private _dbFactory;
    
        public Repository(DbFactory dbFactory)
        {
            _dbFactory = dbFactory;
        }
    
        public void Dispose()
        {
            _dbFactory.Dispose();
        }
    } 
    
  2. 现在使用它:

    ResultObject result;
    using (Repository repo = new Repository(new DbFactory())
    {
        result = repo.Get(somecondition);
    }
    
  3. 或使用嵌套使用:

    using (DbFactory db = new DbFactory())
    {
        using(Repository repo = new Repository(db))
        {
            result = repo.Get(somecondition);
        }
    }