繁体   English   中英

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

[英]Using C#'s 'using' statement with a custom object's function, do I Need to implement IDisposable?

我有一个像这样的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连接?

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

编译器会告诉您是否弄错了-p(它不会让您在非IDisposable上使用using )。

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

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;
}

它将起作用,但是在using {}之后,您将剩下一个内部保存Disposed SqlConnection的sqlConn。 这不是真正有用的情况

您的代码是错误的!

应该是这样的:

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语句将在最后放置连接。

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

然后,是的,“使用”会将您的SqlConnection放置在该块的末尾。 可以将“使用”视为“最终尝试”:在“最终”块中隐式调用了Dispose()。

最后,更干净的代码是:

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

Henk Holterman指出,您的SQLConn对象拥有对已处置连接的引用,至少您的代码读者无需花心思去实现。

为了澄清上面所说的内容:

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

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

返回的对象不需要实现IDisposable,但是using块将无济于事。

MSDN

提供给using语句的对象必须实现IDisposable接口。

尽管您不必调用Dispose(),但是using语句隐式为您完成了此操作。

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

您可以实例化资源对象,然后将变量传递给using语句,但这不是最佳实践。 在这种情况下,即使控制对象可能不再有权访问其非托管资源,该对象在控制离开using块之后仍保留在作用域中。 换句话说,它将不再完全初始化。 如果尝试在using块之外使用该对象,则有引发异常的风险。 因此,通常最好在using语句中实例化对象并将其范围限制为using块。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM