在类级变量上使用using语句是不好的做法吗?

Han*_*ood 9 c# scope using

我的代码类似于以下内容.

class MyController
{
    [ThreadStatic] private DbInterface db;

    public void ImportAllData()
    {
        using (db = new DbInterface())
        {
            var records = PullData();
            PushData(records);
        }
    }

    private DbRecord[] PullData()
    {
        return db.GetFromTableA();
    }

    private void PushData(DbRecord[] records)
    {
        db.InsertIntoTableB(records);
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种选择是维护起来更麻烦.

class MyController
{
    public void ImportAllData()
    {
        using (var db = new DbInterface())
        {
            var records = PullData(db);
            PushData(records, db);
        }
    }

    private DbRecord[] PullData(DbInterface db)
    {
        return db.GetFromTableA();
    }

    private void PushData(DbRecord[] records, DbInterface db)
    {
        db.InsertIntoTableB(records);
    }
}
Run Code Online (Sandbox Code Playgroud)

据我所知,我的第一个实现:

  • 是线程安全的(假设DbInterface是线程安全的),
  • 防止任何其他进程触及db变量,和
  • 确保db即使在例外期间也将始终处置.

using在具有类范围的变量上使用该语句是不好的做法吗?我错过了什么吗?

Ree*_*sey 10

就个人而言,我更喜欢你的第二种选择.

第一个设计的问题是您有效地为设计添加了不必要的耦合.您PullData和PushData方法不能单独使用 - 它们要求首先调用ImportAllData设置和正确清理db变量的调用或其他方法.

第二个选项,虽然稍微多一些代码(虽然不多),但是对于每个方法都非常清楚.每个方法都知道它需要处理DbInterface传递给它的外部实例.将来很少或根本没有机会被滥用.


Eri*_* J. 8

您的第一个变体暴露db在由using块管理的范围之外.这可能会产生意想不到的副作用.例如,另一种方法可能使用甚至处理db.如果您或后来的维护者忘记了隐含的合同,db甚至通过代码中的拼写错误,就会发生这种情况.

我不会使用第一个变体.