using 语句(C# 参考)
using
语句提供可确保正确使用 IDisposable 对象的方便语法。 await using
语句可确保正确使用 IAsyncDisposable 对象。 语言支持实现 System.IAsyncDisposable 接口的异步可释放类型。
示例
下面的示例演示如何使用 using
语句。
string manyLines = @"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";
using (var reader = new StringReader(manyLines))
{
string? item;
do
{
item = reader.ReadLine();
Console.WriteLine(item);
} while (item != null);
}
using 声明不需要大括号:
string manyLines = @"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";
using var reader = new StringReader(manyLines);
string? item;
do
{
item = reader.ReadLine();
Console.WriteLine(item);
} while (item != null);
备注
File 和 Font 是访问非托管资源(本例中为文件句柄和设备上下文)的托管类型的示例。 有许多其他类别的非托管资源和封装这些资源的类库类型。 所有此类类型都必须实现 IDisposable 接口或 IAsyncDisposable 接口。
IDisposable
对象的生存期限于单个方法时,应在 using
语句或 using
声明中声明并实例化它。 using
声明以正确方式在对象上调用 Dispose 方法,当它超出范围时。 当 Dispose 调用时,using
语句导致对象本身超出范围。 在 using
块中,对象是只读的并且无法进行修改或重新分配。 使用 using
声明声明的变量是只读的。 如果对象实现 IAsyncDisposable
而不是 IDisposable
,任一 using
窗体将调用 DisposeAsync 和 awaits
返回的 ValueTask。 有关 IAsyncDisposable 的详细信息,请参阅IAsyncDisposable。
两个 using
窗体均可确保 Dispose(或 DisposeAsync)被调用,即使 using
块中发生异常也是如此。 通过将对象放入 try
块中,然后调用 finally
块中的 Dispose(或 DisposeAsync),可以实现相同的结果;实际上,这就是编译器转换 using
语句和 using
声明的方式。 前面的代码示例在编译时将扩展到以下代码(请注意,使用额外的大括号为对象创建有限范围):
string manyLines = @"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";
{
var reader = new StringReader(manyLines);
try
{
string? item;
do
{
item = reader.ReadLine();
Console.WriteLine(item);
} while (item != null);
}
finally
{
reader?.Dispose();
}
}
较新的 using
语句语法转换为类似的代码。 try
块在声明变量的位置打开。 finally
块添加在封闭块的末尾,通常是在方法的末尾。
有关 try
-finally
语句的详细信息,请参阅 try
一文。
可在单个 using
语句中声明一个类型的多个实例,如下面的示例中所示。 注意,在单个语句中声明多个变量时,不能使用隐式类型的变量 (var
):
string numbers = @"One
Two
Three
Four.";
string letters = @"A
B
C
D.";
using (StringReader left = new StringReader(numbers),
right = new StringReader(letters))
{
string? item;
do
{
item = left.ReadLine();
Console.Write(item);
Console.Write(" ");
item = right.ReadLine();
Console.WriteLine(item);
} while (item != null);
}
也可以使用声明语法,合并同一类型的多个声明,如下面的示例中所示:
string numbers = @"One
Two
Three
Four.";
string letters = @"A
B
C
D.";
using StringReader left = new StringReader(numbers),
right = new StringReader(letters);
string? item;
do
{
item = left.ReadLine();
Console.Write(item);
Console.Write(" ");
item = right.ReadLine();
Console.WriteLine(item);
} while (item != null);
可以实例化资源对象,然后将变量传递到 using
语句,但这不是最佳做法。 在这种情况下,控件退出 using
块以后,对象保留在作用域中,但是可能没有访问其未托管资源的权限。 换而言之,它不再是完全初始化的。 如果尝试在 using
块外部使用该对象,则可能导致引发异常。 因此,最好在 using
语句中实例化该对象并将其范围限制在 using
块中。
string manyLines = @"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";
var reader = new StringReader(manyLines);
using (reader)
{
string? item;
do
{
item = reader.ReadLine();
Console.WriteLine(item);
} while (item != null);
}
// reader is in scope here, but has been disposed
有关释放 IDisposable
对象的详细信息,请参阅IDisposable
。
C# 语言规范
有关详细信息,请参阅 C# 语言规范中的 using 语句。 该语言规范是 C# 语法和用法的权威资料。