C# 在使用块中创建资源与在使用块外部创建资源

C# 在使用块中创建资源与在使用块外部创建资源,c#,disposable,C#,Disposable,例如,可通过以下方式创建一次性资源的新实例: var resource = CreateNewResource(); 下面的编码风格有什么不同(如果有的话) 第一款: var resource = CreateNewResource(); using (resource) { //Use resource } 第二种风格: using (var resource = CreateNewResource()) { //Use resource } 如果我们不打算在using块

例如,可通过以下方式创建一次性资源的新实例:

var resource = CreateNewResource();
下面的编码风格有什么不同(如果有的话)

第一款:

var resource = CreateNewResource();
using (resource)
{
    //Use resource
}
第二种风格:

using (var resource = CreateNewResource())
{
    //Use resource
}
如果我们不打算在using块之外的任何地方使用资源,那么第一种样式的编码实践是不是很糟糕


即使我们希望在using块之外使用资源,是否应该鼓励在using块之外使用一次性资源?

第一个值得注意的区别是,在您的第一个代码片段中,变量资源仍然在using块之后声明,因此有人可以在释放后使用它,这很糟糕

var resource = CreateNewResource();
using (resource)
{
    //Use resource
}
...
// Unknowingly continues to use resource
resource.BadActOnDisposedObject();
如果您确实希望更自由地使用和分配资源,我建议您使用try/finally,如下所示:

Resource resource = null;
try
{
    // do whatever
    resource = CreateNewResource();
    // continue to do whatever
}
finally
{
    if (resource != null)
    {
        resource.Dispose();
        resource = null;
    }
}

这保证了您的资源在任何情况下都会被释放。

第一个值得注意的区别是,在您的第一个代码段中,变量资源仍然在using块之后声明,因此有人可以在释放后使用它,这是不好的

var resource = CreateNewResource();
using (resource)
{
    //Use resource
}
...
// Unknowingly continues to use resource
resource.BadActOnDisposedObject();
如果您确实希望更自由地使用和分配资源,我建议您使用try/finally,如下所示:

Resource resource = null;
try
{
    // do whatever
    resource = CreateNewResource();
    // continue to do whatever
}
finally
{
    if (resource != null)
    {
        resource.Dispose();
        resource = null;
    }
}

这保证您的资源在任何情况下都会被释放。

好的。。因此,这显然是一种不好的做法

很好:

您可以实例化资源对象,然后将变量传递给 使用语句,但这不是最佳实践。在这种情况下,, 控件离开使用块后,对象仍保留在范围内 尽管它可能不再有权访问其非托管 资源。换句话说,它将不再完全初始化。如果 如果尝试在使用块之外使用对象,则可能会导致 要抛出的异常。因此,通常最好 在using语句中实例化对象,并将其范围限制为 正在使用的块


我在网上的某个地方看到过这种风格。在我自己的代码中,每当样式2中的资源声明语句很长时,我都会使用(){}从
中提取声明,然后按照样式1中所述编写代码,以使代码更具可读性。

Ok。。因此,这显然是一种不好的做法

很好:

您可以实例化资源对象,然后将变量传递给 使用语句,但这不是最佳实践。在这种情况下,, 控件离开使用块后,对象仍保留在范围内 尽管它可能不再有权访问其非托管 资源。换句话说,它将不再完全初始化。如果 如果尝试在使用块之外使用对象,则可能会导致 要抛出的异常。因此,通常最好 在using语句中实例化对象,并将其范围限制为 正在使用的块



我在网上的某个地方看到过这种风格。在我自己的代码中,每当样式2中的资源声明语句很长时,我就使用(){}
中提取声明,然后按照样式1中所述编写代码,以使代码更具可读性。

区别在于类实例的处置时间。在使用block时,类的实例将在离开block后进行处理。@SiyavashHamdi:我猜是这样的。第一种编码风格会发生什么?按第一种风格编写代码只是表面现象吗?我在很多地方都见过这种风格。@SiyavashHamdi:第一种风格的资源会发生什么情况?@displayName Re:“第一种风格的资源会发生什么情况?”请参见下面Zuu的回答。@SiyavashHamdi不是真的-在这两种情况下,它们都将在
块的末尾被处理。唯一的区别在于变量范围。区别在于类实例的处置时间。在使用block时,类的实例将在离开block后进行处理。@SiyavashHamdi:我猜是这样的。第一种编码风格会发生什么?按第一种风格编写代码只是表面现象吗?我在很多地方都见过这种风格。@SiyavashHamdi:第一种风格的资源会发生什么情况?@displayName Re:“第一种风格的资源会发生什么情况?”请参见下面Zuu的回答。@SiyavashHamdi不是真的-在这两种情况下,它们都将在
块的末尾被处理。唯一的区别在于变量范围。Ok。显然,我在多个地方看到的第一个样式是不好的。@displayName您在哪里看到它的使用?在公共代码中还是在您的工作场所?@DStanley:Oops。。我被困住了。真的不知道我在哪里看到的。你可以猜一猜D@displayName在我看来,你的第一种风格有点凌乱,因为它在某种程度上暗示了非常严格的控制,使用“使用”,但这种严格性在使用方式上立即消失了。我想如果你想要一些不那么严格的东西,请从代码结构中看清楚。@displayName不想陷害你,只是想知道是否有我不知道的有效用例。好的。显然,我在多个地方看到的第一个样式是不好的。@displayName您在哪里看到它的使用?在公共代码中还是在您的工作场所?@DStanley:Oops。。我被困住了。真的不知道我在哪里看到的。你可以猜一猜D@displayName在我看来,你的第一种风格有点凌乱,因为它在某种程度上暗示了非常严格的控制,使用“使用”,但这种严格性在使用方式上立即消失了。我认为,如果您想要一些不那么严格的内容,请从代码结构中将其明确化。@displayName不想陷害您,只是想知道是否有我不知道的有效用例。如果考虑可读性,您可以在
using()
声明中使用换行符,并将内部部分放在单独的一行。@DStanley:有时调用类似于
var resource=createNewResourceByCallingalargenemedMethod(abc、def、ghi、jklmnopqrstu、vwxyz)方法