使用 C# 的“using” 带有自定义对象函数的语句,我需要实现 IDisposable 吗?

发布于 2024-07-21 19:02:34 字数 857 浏览 6 评论 0原文

我有一个像这样的 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(); 
}

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

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

I have an sqlConnection manager class like so:

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

If I use a function with the 'using' statement like:

var conn = new SQLConn();

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

    conn.Open(); 
    DoSomething(); 
}

Does the using statement dispose of the connection automatically since conn.Connection() returns a SqlConnection object? Or, do I have to implement IDisposable and a custom Dispose method on the SqlConn class?

Is this even a good way at all? I'm working with legacy code and I'm not able to use an ORM yet but is there a way to simplify this existing pattern to manage/create SQL connections?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

虚拟世界 2024-07-28 19:02:34

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

然后,是的,“使用”将在块的末尾处理您的 SqlConnection。 将“using”视为“try-finally”:在“finally”块中有对 Dispose() 的隐式调用。

最后,更简洁的代码是:

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

至少代码的读者不必费力去意识到,正如 Henk Holterman 指出的那样,您的 SQLConn 对象保存了对已释放连接的引用。

to answer your headline question, you must implement IDisposable in the class whose object you're using with "using". Otherwise, you'll get a compile-time error.

Then, yes, "using" will dispose your SqlConnection at the end of the block. Think of "using" as a "try-finally": there is an implicit call to Dispose() in the "finally" block.

Finally, cleaner code would be:

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

At least readers of your code won't have to make the mental effort to realize as Henk Holterman pointed out that your SQLConn object holds a reference to a disposed connection.

毁虫ゝ 2024-07-28 19:02:34

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

The using statement will look at the final type of the expression - i.e. whatever is returned from .Connection(); if this returns something that is IDisposable, then you're OK.

The compiler will tell you if you get it wrong ;-p (it won't let you use using on something that isn't IDisposable).

You should probably watch out for where you are creating two connections:

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

    c.Open(); 
    DoSomething(); 
}

and possibly:

public SqlConnection Connection()
{
  if(sqlConn == null) sqlConn = new SqlConnection(connStr); // <== edit
  return sqlConn;
}
烟酒忠诚 2024-07-28 19:02:34

它可以工作,但在 using {} 之后,您将得到一个 sqlConn,它内部保存一个已处理的 SqlConnection。 这不是一个真正有用的情况

It will work but after the using {} you will be left with an sqlConn that internally holds a Disposed SqlConnection. Not a really useful situation

不及他 2024-07-28 19:02:34

你的代码是错误的!

应该是这样的:

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

Your code is wrong!

shoudl be something like this:

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

That way the using statement will dispose the connection at the end.

仙女山的月亮 2024-07-28 19:02:34

不,你不需要,只要返回的对象是 IDisposable 即可。

返回的对象不需要实现 IDisposable,但这样 using 块就没有任何作用。

No you do not, as long as the returned object is IDisposable.

The returned object needs not to implement IDisposable, but then the using block would serve no purpose.

咆哮 2024-07-28 19:02:34

来自 MSDN

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

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

From MSDN:

The object provided to the using
statement must implement the
IDisposable interface.

You do not have to call Dispose() though, the using statement implicitly does this for you.

胡大本事 2024-07-28 19:02:34

看起来连接会正确关闭,但不建议这样做:

您可以实例化资源
对象,然后将变量传递给
using 语句,但这不是
最佳实践。 在这种情况下,
控制后对象仍保留在范围内
留下 using 块,即使它
可能无法再访问
其非托管资源。 其他
话,它将不再完全
已初始化。 如果您尝试使用
using 块之外的对象,您
导致异常的风险
抛出。 正因如此,
通常更好地实例化
using 语句中的对象和
将其范围限制为 using 块。

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

It seems the connection will be closed properly, but this is not recommended:

You can instantiate the resource
object and then pass the variable to
the using statement, but this is not a
best practice. In this case, the
object remains in scope after control
leaves the using block even though it
will probably no longer have access to
its unmanaged resources. In other
words, it will no longer be fully
initialized. If you try to use the
object outside the using block, you
risk causing an exception to be
thrown. For this reason, it is
generally better to instantiate the
object in the using statement and
limit its scope to the using block.

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

一页 2024-07-28 19:02:34

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

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

To clarify what is being said above:

Any object you need to use with using should be disposed at the end of the using statement. The compiler thus need to make sure that your type implements the IDisposable interface when it sees using on that type object or it won't let you go.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文