IDisposable 对象是否在方法 RETURN 之后自行处理?
Is IDisposable object disposed itself after RETURN from method?
比方说,我有以下代码:
theIDisposableObject myMethod()
{
theIDisposableObject smth=new theIDisposableObject();
return smth;
}
void Main()
{
var A= myMethod();
...
A.Dispose();
}
我做得对吗?我的意思是,smth
是自行处理的,因为它被 A
变量引用(正在处理),甚至 smth
需要自己处理(如果是这样,只有 using
是解决方案)?
对象是否已处理?是的
有没有更好的方法?是的。使用 using 语句。
AnIDisposableObject myMethod()
{
AnIDisposableObject smth=new AnIDisposableObject();
return smth;
}
(...)
using( var a = myMethod())
{
}
// a is disposed here.
这很重要,因为如果在 var A= myMethod();
和 A.Dispose();
之间抛出异常,A
将不会被处理。不好。
C#8
在C#8
事情变得更容易了。
if (...)
{
using FileStream f = new FileStream(@"C:\users\jaredpar\using.md");
// statements
}
// Equivalent to
if (...)
{
using (FileStream f = new FileStream(@"C:\users\jaredpar\using.md"))
{
// statements
}
}
The lifetime of a using local will extend to the end of the scope in which it is declared. The using locals will then be disposed in the reverse order in which they are declared.
{
using var f1 = new FileStream("...");
using var f2 = new FileStream("..."), f3 = new FileStream("...");
...
// Dispose f3
// Dispose f2
// Dispose f1
}
是否已处理?在大多数情况下是的。
您向我们展示的代码毫无意义。在函数调用和 Dispose 调用之间 必须 有其他东西,甚至 考虑 像这样写它。这些都可以抛出异常,随便跳过 dispose。
我有一个 IDisposeables 规则:
切勿将 IDisposeable 的创建和处理拆分为多段代码。 创建。采用。处置。全部在同一段代码中,最好使用 Using 块。其他一切都只是自找麻烦。
罕见的例外是当你包裹一些 Disposeable 时。在这种情况下,您实现 iDisposeable 的唯一目的是将 Dispose 调用中继到包含的实例。顺便说一句。大约 95% 的 IDispose 实现的原因 - 你可以环绕一些可能需要 Dispose 的东西。
using 只是一个 shorthand for a: try, finally, NullCheck, Dispose。最后 运行s 在所有可能的情况下:它 运行s 在 return 之后。它 运行 是例外。它 运行 在 GOTO 上,继续,其他跳出它的块。它不会 运行 OS 终止进程,但在这一点上它有点是 OS/Finalizers 的责任。
最好的方法当然是不要 return 一些可以从函数中删除的东西。无论它有什么数据,只需将其映射到不使用 Disposeables 的东西即可。 IIRC 在使用 SQLDataReader 时(需要打开连接),这正是发生的情况。您将查询 return 值映射到不需要打开连接的任何其他集合。
如果你做不到,为了安心,我会这样修改你的代码:
void Main()
{
using(var A= myMethod()){
//Anything you want to do with that variable
}
//using takes care of the Dispose call
}
现在任何事情都可能发生,我知道使用会处理处置。
比方说,我有以下代码:
theIDisposableObject myMethod()
{
theIDisposableObject smth=new theIDisposableObject();
return smth;
}
void Main()
{
var A= myMethod();
...
A.Dispose();
}
我做得对吗?我的意思是,smth
是自行处理的,因为它被 A
变量引用(正在处理),甚至 smth
需要自己处理(如果是这样,只有 using
是解决方案)?
对象是否已处理?是的
有没有更好的方法?是的。使用 using 语句。
AnIDisposableObject myMethod()
{
AnIDisposableObject smth=new AnIDisposableObject();
return smth;
}
(...)
using( var a = myMethod())
{
}
// a is disposed here.
这很重要,因为如果在 var A= myMethod();
和 A.Dispose();
之间抛出异常,A
将不会被处理。不好。
C#8
在C#8 事情变得更容易了。
if (...) { using FileStream f = new FileStream(@"C:\users\jaredpar\using.md"); // statements } // Equivalent to if (...) { using (FileStream f = new FileStream(@"C:\users\jaredpar\using.md")) { // statements } }
The lifetime of a using local will extend to the end of the scope in which it is declared. The using locals will then be disposed in the reverse order in which they are declared.
{ using var f1 = new FileStream("..."); using var f2 = new FileStream("..."), f3 = new FileStream("..."); ... // Dispose f3 // Dispose f2 // Dispose f1 }
是否已处理?在大多数情况下是的。
您向我们展示的代码毫无意义。在函数调用和 Dispose 调用之间 必须 有其他东西,甚至 考虑 像这样写它。这些都可以抛出异常,随便跳过 dispose。
我有一个 IDisposeables 规则:
切勿将 IDisposeable 的创建和处理拆分为多段代码。 创建。采用。处置。全部在同一段代码中,最好使用 Using 块。其他一切都只是自找麻烦。
罕见的例外是当你包裹一些 Disposeable 时。在这种情况下,您实现 iDisposeable 的唯一目的是将 Dispose 调用中继到包含的实例。顺便说一句。大约 95% 的 IDispose 实现的原因 - 你可以环绕一些可能需要 Dispose 的东西。
using 只是一个 shorthand for a: try, finally, NullCheck, Dispose。最后 运行s 在所有可能的情况下:它 运行s 在 return 之后。它 运行 是例外。它 运行 在 GOTO 上,继续,其他跳出它的块。它不会 运行 OS 终止进程,但在这一点上它有点是 OS/Finalizers 的责任。
最好的方法当然是不要 return 一些可以从函数中删除的东西。无论它有什么数据,只需将其映射到不使用 Disposeables 的东西即可。 IIRC 在使用 SQLDataReader 时(需要打开连接),这正是发生的情况。您将查询 return 值映射到不需要打开连接的任何其他集合。
如果你做不到,为了安心,我会这样修改你的代码:
void Main()
{
using(var A= myMethod()){
//Anything you want to do with that variable
}
//using takes care of the Dispose call
}
现在任何事情都可能发生,我知道使用会处理处置。