解决与
本文介绍以下编译器错误:
-
CS0245: 析构函数和
object.Finalize不能直接调用。请考虑调用IDisposable.Dispose(如果可用)。 -
CS0728:可能错误地将值赋给作为 using 或
lock语句的参数的局部变量。调用Dispose或解锁将发生在该局部变量的原始值上。 -
CS1674:在 using 语句中使用的类型必须能够隐式转换为“
System.IDisposable”。 -
CS8410: 异步
using语句中使用的类型必须隐式转换为“”System.IAsyncDisposable或实现合适的“”DisposeAsync方法。 -
CS8417: 在异步 using 语句中使用的类型必须实现 '
System.IAsyncDisposable' 或实现合适的 'DisposeAsync' 方法。你的意思是 'using' 而不是 'await using'? -
CS8418:using 语句中使用的类型必须实现“
System.IDisposable”。如果你的意思是“await using”而不是“using”吗? - CS8647: 不能直接在 switch 语句块中使用 using 变量(请考虑使用大括号)。
-
CS8648: 使用
goto声明后无法跳转到某个位置。 - CS8649:不能跳转到同一块中使用声明之前的某个位置。
- CS9229: 不能使用声明放置修饰符。
实现 IDisposable 和 IAsyncDisposable
以下编译器错误和警告指示实现或使用释放模式时出现问题:
-
CS0245:析构函数和
object.Finalize不能被直接调用。请考虑调用IDisposable.Dispose(如果可用)。 -
CS1674:在 using 语句中使用的类型必须能够隐式转换为“
System.IDisposable”。 -
CS8410: 异步
using语句中使用的类型必须隐式转换为“”System.IAsyncDisposable或实现合适的“DisposeAsync”方法。 -
CS8417: 异步
using语句中使用的类型必须实现“”System.IAsyncDisposable或实现合适的“”DisposeAsync方法。你的意思是'using'而不是''await using? -
CS8418:using 语句中使用的类型必须实现
System.IDisposable。是否意味着使用'await using'而不是'using'?
using 语句可确保在using块结束时正确处置资源。 若要对 using 语句使用类型,它必须实现适当的处置接口。 对于同步 using 语句,类型必须实现 IDisposable。 对于异步 await using 语句,类型必须实现 IAsyncDisposable。
-
无法直接调用 Finalize(CS0245):不能直接调用析构函数或 Object.Finalize 方法。 当对象不再被引用时,垃圾回收器会自动执行终止器。 对于确定性清理,请改为实现 IDisposable 和调用
Dispose该方法。 - 类型必须实现 IDisposable(CS1674):只有实现IDisposable的类型才能在
using语句中使用。 值类型不实现此接口,不能假定没有适当约束的泛型类型参数是可释放的。 在使用泛型类型时,应用类型约束,例如where T : IDisposable。 -
类型必须实现 IAsyncDisposable (CS8410):与
await using一起使用的类型必须实现 IAsyncDisposable 或提供适当的DisposeAsync方法。 如果类型不支持异步处置,请改用同步using语句或实现所需的接口。 -
不匹配的处置模式(CS8417,CS8418): 当您与仅实现IDisposable的类型一起使用
await using时,会发生 CS8417。 将同步using用于仅实现 IAsyncDisposable的类型时,会发生 CS8418。 将using关键字与类型实现的接口匹配,或者如果需要支持这两种模式,则实现这两个接口。
有关详细信息,请参阅 终结器、 实现 Dispose 方法和 实现 DisposeAsync 方法。
使用变量范围和控制流
以下编译器错误和警告与控制流语句中变量的 using 不正确用法相关:
-
CS0728:可能对局部变量进行不正确的赋值,该变量是
using或lock语句的参数。Dispose调用或解锁将在该局部变量的原始值上发生。 - CS8647: 不能直接在 switch 语句块中使用 using 变量,建议使用大括号。
-
CS8648: 使用
goto声明后无法跳转到某个位置。 -
CS8649:
goto不能跳转到同一代码块内using声明之前的位置。
使用 using 特定范围规则声明的变量可阻止资源泄漏。 编译器强制实施这些规则,以确保正确处置。
赋值到使用变量(CS0728):此警告表明你将一个新值赋给了
using语句中的资源变量。 释放调用发生在原始值上,而不是新分配的值,这可能会导致资源泄漏。 在using声明语句中初始化资源,而不是将其分配到稍后的语句中。在 switch 节中使用变量(CS8647):
using声明创建了一个在其范围结束时释放的变量。 直接在没有大括号的 switch 语句中使用时,范围不明确,可能导致歧义和错误。 将 switch 节内容用大括号括起来以明确其范围。Goto 语句和使用声明(CS8648、CS8649):不能使用
goto语句跳转using声明,因为跳转会跳过适当的资源管理。 CS8648 发生在向前跳过using声明时,CS8649 发生在向后跳转到using声明之前的位置时。 重构代码以使用结构化控制流(如循环)或将using声明移到跳转目标之外。
有关详细信息,请参阅 using 语句。
声明不正确using
- CS9229:不能在 using 声明上使用修饰符。
包含在 using 声明中的变量声明不能包括以下任何修饰符:
conststaticvolatilereadonly- 辅助功能修饰符:
public、protected、internal、private、protected internal或private protected
以下示例生成 CS9229:
using System;
class Program
{
static void Main()
{
// error CS9229: Modifiers cannot be placed on using declarations.
public using var resource = new Resource();
// error CS9229: Modifiers cannot be placed on using declarations.
static using var anotherResource = new Resource();
}
}
class Resource : IDisposable
{
public void Dispose() { }
}
若要更正此错误,请从 using 声明中删除修饰符:
using var resource = new Resource();
有关详细信息,请参阅 using 语句。