C# 如果显式处置表单,是否需要使用块?

C# 如果显式处置表单,是否需要使用块?,c#,winforms,C#,Winforms,我一直收到一个Win32Exception,其中有一个臭名昭著的错误:创建窗口句柄时出错。但直到最近,我才意识到它发生在试图调用Environment.Exit(0)的一行上,我随后去掉了它,然后让窗体自行关闭 所以我的问题是,每当我知道我不再需要表单时,我总是调用base.Close()和base.Dispose(true)。如果我这样做,是否真的需要使用块将表单放入中?是。如果不使用using,如果您的代码在到达显式Dispose调用之前出于任何原因引发异常,您的对象将不会被释放。是。如果不

我一直收到一个
Win32Exception
,其中有一个臭名昭著的错误:
创建窗口句柄时出错。
但直到最近,我才意识到它发生在试图调用
Environment.Exit(0)
的一行上,我随后去掉了它,然后让窗体自行关闭


所以我的问题是,每当我知道我不再需要表单时,我总是调用
base.Close()
base.Dispose(true)
。如果我这样做,是否真的需要使用块将表单放入
中?

是。如果不使用
using
,如果您的代码在到达显式
Dispose
调用之前出于任何原因引发异常,您的对象将不会被释放。

是。如果不使用
using
,如果您的代码在到达显式
Dispose
调用之前出于任何原因引发异常,那么您的对象将不会被释放。

不太可能。它基本上为您提供了更清晰、简洁的语法。在内部,使用创建一个try..catch..finally块(),您可以根据需要复制它

SomeClass obj = null;
try
{
    obj = new SomeClass();
    obj.SomeOperation();
}
catch()
{
}
finally
{
    if(obj != null)
        obj.Dispose();
}

不确定是否有必要这样做,但如果您可以使用单一的statemenet来实现,为什么要这样做。

不太清楚。它基本上为您提供了更清晰、简洁的语法。在内部,使用创建一个try..catch..finally块(),您可以根据需要复制它

SomeClass obj = null;
try
{
    obj = new SomeClass();
    obj.SomeOperation();
}
catch()
{
}
finally
{
    if(obj != null)
        obj.Dispose();
}

不确定是否有必要这样做,但如果可以使用单次使用statemenet,为什么要这样做。

实际上没有必要。然而,using块是一种方便且故障安全的编程结构。例如,忘记将调用添加到dispose是很常见的。当您选择“使用”块时,您无需担心处理对象。因此,最好练习对所有一次性物品使用“使用”块

您没有提到调用Dispose方法的位置。它应该始终位于finally块中,如下所述

DisposableClass disposableObj = null;
try
{
    disposableObj = new DisposableClass();
    ....
    ....
}
finally
{
    if( disposableObj != null)
    {
       disposableObj.Dispose();
    }
}
上述代码可以简化为

using(DisposableClass disposableObj = new DisposableClass())
{
  .....
  .....
}

其实没有必要。然而,using块是一种方便且故障安全的编程结构。例如,忘记将调用添加到dispose是很常见的。当您选择“使用”块时,您无需担心处理对象。因此,最好练习对所有一次性物品使用“使用”块

您没有提到调用Dispose方法的位置。它应该始终位于finally块中,如下所述

DisposableClass disposableObj = null;
try
{
    disposableObj = new DisposableClass();
    ....
    ....
}
finally
{
    if( disposableObj != null)
    {
       disposableObj.Dispose();
    }
}
上述代码可以简化为

using(DisposableClass disposableObj = new DisposableClass())
{
  .....
  .....
}
无需使用
块对封装在
中的对象调用
Dispose()
。但是,关于您的问题,最好使用
块将一次性对象封装在
中,因为这样可以确保始终调用该对象上的
Dispose()
方法

在任何情况下,此代码:

using (var disposableObject = new DisposableObject())
{
    // Perform some action...
}
实际上相当于:

try
{
    var disposableObject = new DisposableObject();
    // Perform some action...
}
finally { disposableObject.Dispose(); }
这是因为在内部,
using
块将始终对对象调用
Dispose()
。实际上,作为使用
语句实现
的要求,您选择的对象必须实现
IDisposable
,以便进行编译

在使用
块的
末尾添加一个额外的
Dispose()
调用是不必要的,也是多余的。

没有必要对使用
块封装在
中的对象调用
Dispose()
。但是,关于您的问题,最好使用
块将一次性对象封装在
中,因为这样可以确保始终调用该对象上的
Dispose()
方法

在任何情况下,此代码:

using (var disposableObject = new DisposableObject())
{
    // Perform some action...
}
实际上相当于:

try
{
    var disposableObject = new DisposableObject();
    // Perform some action...
}
finally { disposableObject.Dispose(); }
这是因为在内部,
using
块将始终对对象调用
Dispose()
。实际上,作为使用
语句实现
的要求,您选择的对象必须实现
IDisposable
,以便进行编译


在使用
块的
末尾添加额外的
Dispose()
调用是不必要和多余的。

错误<代码>使用
是一种推荐的方法,但它只不过是一种语法糖,因此在任何情况下都不必使用本身。如果可以以适当的方式手动调用
Dispose
,那么这没有什么错。唯一一种异常安全的“适当方式”是在finally块中进行处理,在大多数情况下,使用
比使用
更可取。错误<代码>使用
是一种推荐的方法,但它只不过是一种语法糖,因此在任何情况下都不必使用
本身。如果可以以适当的方式手动调用
Dispose
,那么这没有什么错。唯一一种异常安全的“适当方式”是在finally块中进行Dispose,在大多数情况下,使用
比使用
更可取。