拥有一次性场地的类型应该是一次性的.怎么解决这个警告?

Pra*_*een 6 c# garbage-collection dispose idisposable

我尝试使用运行代码分析选项VisualStudio 2012,因此我得到了一个警告

CA1001  Types that own disposable fields should be disposable
Implement IDisposable on 'DBConnectivity' 
because it creates members of the following IDisposable types: 'SqlConnection', 'SqlCommand'.
Run Code Online (Sandbox Code Playgroud)

我在SO中提到了一些问题,但是我无法理解这一点,IDisposable 并且关注的是该类,负责此警告.

class DBConnectivity
    {
        public SqlConnection connection = null;
        public SqlCommand command = null;
        public SqlDataReader dataReader = null;
        public string connectionString = null;
        public List<MasterTableAttributes> masterTableList;
        public DBConnectivity()
        {
            connectionString = ConfigurationManager.ConnectionStrings["Master"].ConnectionString;
            connection = new SqlConnection(connectionString.ToString());

            //-----Master table results 
            connection.Open();
            string masterSelectQuery = "SELECT * FROM MASTER_TABLE";
            command = new SqlCommand(masterSelectQuery, connection);
            dataReader = command.ExecuteReader();
            masterTableList = new List<MasterTableAttributes>();

            while (dataReader.Read())
            {
                MasterTableAttributes masterTableAttribute = new MasterTableAttributes()
                {
                    fileId = Convert.ToInt32(dataReader["Id"]),
                    fileName = Convert.ToString(dataReader["FileName"]),
                    frequency = Convert.ToString(dataReader["Frequency"]),
                    scheduledTime = Convert.ToString(dataReader["Scheduled_Time"])
                };
                masterTableList.Add(masterTableAttribute);
            }
            dataReader.Close();
            connection.Close();
        }
    }
Run Code Online (Sandbox Code Playgroud)

我对实现IDisposable非常困惑.任何帮助表示赞赏

Mar*_*ell 8

我完全同意编译器 - 你需要在这里处理你的字段,或者(如前所述) - 首先不要让它们成为字段:

class DBConnectivity : IDisposable // caveat! read below first
{
    public void Dispose() {
        if(connection != null) { connection.Dispose(); connection = null; }
        if(command != null) { command.Dispose(); command = null; }
        if(dataReader != null) { dataReader.Dispose(); dataReader = null; }
    }
Run Code Online (Sandbox Code Playgroud)

请注意,您将通过此类型使用 using(...)


然而!看起来静态方法更合适:

static class DBConnectivity
{
    public static List<MasterTableAttributes> GetMasterTableList()
    {
        var connectionString = ConfigurationManager.ConnectionStrings["Master"].ConnectionString;
        using(var connection = new SqlConnection(connectionString))
        {
            connection.Open();
            const string masterSelectQuery = "SELECT * FROM MASTER_TABLE";
            using(var command = new SqlCommand(masterSelectQuery, connection))
            using(var dataReader = command.ExecuteReader())
            {
                var masterTableList = new List<MasterTableAttributes>();

                while (dataReader.Read())
                {
                    MasterTableAttributes masterTableAttribute = new MasterTableAttributes()
                    {
                        fileId = Convert.ToInt32(dataReader["Id"]),
                        fileName = Convert.ToString(dataReader["FileName"]),
                        frequency = Convert.ToString(dataReader["Frequency"]),
                        scheduledTime = Convert.ToString(dataReader["Scheduled_Time"])
                    };
                    masterTableList.Add(masterTableAttribute);
                }
                return masterTableList;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者像"小巧玲珑"这样的工具更简单:

static class DBConnectivity
{
    public static List<MasterTableAttributes> GetMasterTableList()
    {
        var connectionString = ConfigurationManager.ConnectionStrings["Master"].ConnectionString;
        using(var connection = new SqlConnection(connectionString))
        {
            connection.Open();
            const string sql = "SELECT Id as [FileId], FileName, Frequency, Scheduled_Time as [ScheduledTime] FROM MASTER_TABLE";
            return connection.Query<MasterTableAttributes>(sql).ToList();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @ user1671639但是*为什么*你在使用它们?他们显然没有任何有用的*对象*(因为它们在理论上已被关闭) - 让调用者声明他们自己的变量.另外:你没有**没有正确关闭`dataReader`等; 首先,它们应该被**处置**(它们不存在),其次:如果你当前的代码出现任何问题,你就失去了与以太网的开放联系; 您应该使用`using`块来确保连接,命令和阅读器都被处理*即使出现错误*.我举了上面的例子. (4认同)