thd*_*thd 2 c# dispose idisposable
我知道当你有以下代码时,在StreamReader对象上调用Dispose()方法:
//Sample 1
using (StreamReader sr1 = new StreamReader(@"C:\Data.txt"))
{
string s1 = sr1.ReadToEnd();
//Do something with s1...
}
Run Code Online (Sandbox Code Playgroud)
但是,如果您编写这样的代码(示例2),Dispose()方法也会被调用吗?
//Sample 2
StreamReader sr2 = new StreamReader(@"C:\Data.txt");
using (sr2)
{
string s2 = sr2.ReadToEnd();
//Do something with s2...
}
Run Code Online (Sandbox Code Playgroud)
是的,一点没错.详情见第8.13节.您的确切问题没有简明陈述,但是:
表格的使用声明
Run Code Online (Sandbox Code Playgroud)using (expression) statement具有相同的三种可能的扩展,但在这种情况下
ResourceType隐式地是表达式的编译时类型,并且资源变量在嵌入语句中是不可访问的,并且是不可访问的.
所提到的"三种可能的扩展"涵盖了同时声明变量的更常见情况.基本上重要的是除了变量的范围外,它的行为方式相同.Dispose仍然会被调用 - 否则根本就没有必要using发表声明:)
请注意,两者在块中的有效性方面并不完全相同,因为using语句声明的变量是只读的.所以这是有效的:
// Warning but no error
MemoryStream ms = new MemoryStream();
using (ms)
{
ms = null;
}
Run Code Online (Sandbox Code Playgroud)
但这不是:
using (MemoryStream ms = new MemoryStream())
{
// error CS1656: Cannot assign to 'ms' because it is a 'using variable'
ms = null;
}
Run Code Online (Sandbox Code Playgroud)
请注意,即使在有效的情况下,它的原始值ms也用于处置.编译器明确了这一点:
警告CS0728:可能不正确地分配给本地'ms',这是using语句或lock语句的参数.Dispose调用或解锁将发生在本地的原始值上.
请注意,此表单不会生成警告:
// No warning
MemoryStream ms;
using (ms = new MemoryStream())
{
ms = null;
}
Run Code Online (Sandbox Code Playgroud)
另一方面,除此之外,他们真的会以同样的方式行事.
编辑:正如bzlm所指出的那样,在using声明之后变量仍然在范围内的事实意味着它通常不是一个好主意.但是,已经放置的物体并不总是不可用.例如:
MemoryStream ms = new MemoryStream();
using (ms)
{
// Do stuff
}
byte[] data = ms.ToArray();
Run Code Online (Sandbox Code Playgroud)
这样可以正常工作 - MemoryStream即使数据处理完毕也可以保存数据.虽然我觉得有点不对劲.
是的,Dispose()在两个例子中都会被调用.它们在功能上是等效的,除了在第二个例子中,处理的StreamReader仍然在范围内.因此,第一种方法是优选的,因为使用被处置物体通常是坏主意.
然而,正如其他人所指出的那样,使用被处理物体有时是可以的.在这种情况下,您可能想要使用第二个示例.但是你必须知道你在做什么,如果可能的话我会尽量避免.