使用C#的'using'语句和自定义对象的函数,我是否需要实现IDisposable?

时间:2009-05-27 10:31:21

标签: c# idisposable sqlconnection

我有一个像这样的sqlConnection管理器类:

public class SQLConn {
  public string connStr = System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"];

  private SqlConnection sqlConn;

  public SqlConnection Connection()
  {
      sqlConn = new SqlConnection(connStr);

      return sqlConn;
  }

  public void Open()
  {
        sqlConn .Open();
  }
}

如果我使用带有'using'语句的函数,如:

var conn = new SQLConn();

using (conn.Connection()) 
{ 
    String query = "Select * from table";
    objSql = new SqlCommand(query, conn.Connection());      

    conn.Open(); 
    DoSomething(); 
}

由于conn.Connection()返回SqlConnection对象,using语句是否会自动处理连接?或者,我是否必须在SqlConn类上实现IDisposable和自定义Dispose方法?

这甚至是一个好方法吗?我正在使用遗留代码,但我还无法使用ORM,但有没有办法简化现有模式来管理/创建SQL连接?

8 个答案:

答案 0 :(得分:12)

using语句将查看表达式的最终类型 - 即从.Connection()返回的任何内容;如果这返回的内容为IDisposable,那么你就可以了。

编译器会告诉您是否出错;-p(不允许您对不是using的内容使用IDisposable

您应该注意创建两个连接的位置:

using (var c = conn.Connection()) // <==edit
{ 
    String query = "Select * from table";
    objSql = new SqlCommand(query, c); // <==edit

    c.Open(); 
    DoSomething(); 
}

可能:

public SqlConnection Connection()
{
  if(sqlConn == null) sqlConn = new SqlConnection(connStr); // <== edit
  return sqlConn;
}

答案 1 :(得分:5)

它会起作用但在using {}之后你会留下一个内部持有Disposed SqlConnection的sqlConn。不是一个非常有用的情况

答案 2 :(得分:1)

你的代码错了!应该是这样的:

Dim conn as New SQLConn();
Dim sqlConnection New SQLConnection();

sqlConnection = conn.Connection();

using (sqlConnection) 
{ 
    String query = "Select * from table";
    objSql = new SqlCommand(query, sqlConnection);      

    conn.Open(); 
    DoSomething(); 
}

这样,using语句将在最后处理连接。

答案 3 :(得分:1)

要回答您的标题问题,您必须在您使用“使用”对象的类中实现IDisposable。否则,您将收到编译时错误。

然后,是的,“using”会在块的末尾处理你的SqlConnection。将“使用”想象为“try-finally”:在“finally”块中隐式调用Dispose()。

最后,更清洁的代码将是:

using( SqlConnection = new SqlConnection( connStr ) {
    // do something
}

至少读者的代码不必花费精力去实现,因为Henk Holterman指出你的SQLConn对象持有对已处置连接的引用。

答案 4 :(得分:1)

澄清上述内容:

您需要使用的任何对象都应该放在using语句的末尾。因此,编译器需要确保您的类型在看到使用该类型对象时实现IDisposable接口,或者它不会让您离开。

答案 5 :(得分:0)

不,不,只要返回的对象是IDisposable。

返回的对象不需要实现IDisposable,但是使用block将没有用处。

答案 6 :(得分:0)

来自MSDN

  

提供给使用的对象   声明必须执行   IDisposable接口。

您不必调用Dispose(),using语句会隐式为您执行此操作。

答案 7 :(得分:0)

似乎连接将正确关闭,但不建议这样做:

  

您可以实例化资源   对象然后将变量传递给   使用声明,但这不是一个   最佳实践。在这种情况下,   对象在控制后仍然在范围内   即使它离开使用块   将来可能无法访问   它的非托管资源。其他   话说,它将不再完整   初始化。如果你试图使用   在使用块之外的对象,你   造成例外的风险   抛出。因此,它是   通常更好地实例化   using语句中的对象和   将其范围限制为使用块。

http://msdn.microsoft.com/en-us/library/yh598w02.aspx