Создание класса IDisposable в C #, который очищает SqlConnection, когда закончите с - PullRequest
4 голосов
/ 07 января 2010

В ответ на предыдущий вопрос кто-то рекомендовал:

имеет SqlConnection переменную-член вашего класса, но делает класс IDisposable и избавляется от SqlConnection, когда класс удаляется

Я собрал реализацию этого предложения (ниже), но хотел проверить, правильна ли эта реализация (очевидно, в настоящее время она ничего не делает, кроме открытия соединения, но идея в том, что там будут методы, которые бы использовать соединение и которое сможет положиться на него существующее и открытое).

public class DatabaseRecord : IDisposable
{
    protected SqlConnection connection;

    public DatabaseRecord()
    {
        connection = new SqlConnection("ConnectionString");
        connection.Open();
    }

    // IDisposable implementation

    private bool disposed;
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }


    private void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                connection.Dispose();
            }
            disposed = true;
        }

    }

    // Destructor
    ~DatabaseRecord()
    {
        Dispose(false);
    }
}

Будет ли это работать? Будут ли классы, использующие экземпляры DatabaseRecord, делать что-то особенное, или будет автоматически вызываться Dispose после того, как экземпляры больше не используются или на них не ссылаются? Является ли это более эффективным / лучшим, чем использование using (var connection = new SqlConnection("...")) { } в каждом отдельном теле метода, где требуется соединение?

Ответы [ 4 ]

5 голосов
/ 07 января 2010

SqlConnection является управляемым ресурсом и должен располагаться в блоке if (disposing). Классы, использующие ваш класс, должны располагать им, в идеале, с блоком using. Будет ли это лучше, чем отдельные using блоки для SqlConnections, будет зависеть от других методов этого класса и от того, как они используются.

3 голосов
/ 07 января 2010

Все советы, которые я видел, говорят о том, что DbConnection s следует хранить в течение минимального времени, поэтому формат, который я бы предпочел видеть в коде, который я рассматриваю, -

using (var connection = new SqlConnection("...")) { ... }
2 голосов
/ 07 января 2010

connection.Dispose() следует переместить в блок if (disposing) { ... }. Вызов Close() не требуется, потому что Dispose() закроет соединение, когда соединение открыто.

1 голос
/ 07 января 2010

Это будет работать, и это будет более эффективно, чем использование нескольких операторов. Код, использующий класс DatabaseRecord, может делать это внутри оператора using, чтобы он автоматически очищался там, когда выходит из цикла.

Однако одна рекомендация заключается в том, чтобы в методе Dispose проверить состояние объекта Connection и закрыть его, если он все еще открыт, перед вызовом dispose.

...