我需要使用多个using语句吗?

3

为了实用性考虑,这两个类都是一次性使用的。

我知道 using 块的作用。但我不确定它可以或需要以哪些方式使用。

例如,以下用法是否正确?

using (MyClass myClass = new MyClass(params))
{
     myClass.name = "Steve";

     SecondClass myClassSecond = new SecondClass(params);
     myClassSecond.name = "George";
     myClassSecond.msg = "Hello Man in the Yellow Hat";
}

这两个类都被处理了吗?

还是说我需要在using语句内同时使用两个类?

using (MyClass myClass = new MyClass(params))
{
     myClass.name = "Steve";

     using (SecondClass myClassSecond = new SecondClass(params))
     {
          myClassSecond.name = "George";
          myClassSecond.msg = "Hello Man in the Yellow Hat";
     }
}

上述内容是否正确,或者有更好的使用多个using语句的方法?

3
这些类是否实现了IDisposable接口?这是使用using的必要条件和原因。 - Hans Kesting
1
这取决于你对 MyClassSecondClass 的实现,以及你何时需要将这些对象 Dispos() - Richard JP Le Guen
dup?https://dev59.com/9nRB5IYBdhLWcg3wn4fc - saj
相关/重复:https://dev59.com/kk_Ta4cB1Zd3GeqPFPbz https://dev59.com/eXE95IYBdhLWcg3wf-AF http://stackoverflow.com/questions/16861329/best-practice-to-avoid-multiple-disposals-with-the-using-keyword-in-c-sharp - user7116
两者都是可丢弃的。抱歉没有提供足够的细节。 - James Wilson
1
在你的第一个例子中,using 块的结尾不会自动处理 myClassSecond 对象,仅仅因为它超出了作用域。只有在 using 括号内提到的对象才会被处理。所以那是不正确的。你必须像最后一个例子一样“嵌套” using 语句。 - Jeppe Stig Nielsen
9个回答

3

使用块在处理任何实现 IDisposable 接口的内容时非常方便。根据MSDN

[using 语句] 定义了一个作用域,在该作用域之外对象或多个对象将被处理。

因此,这相当于:

IDisposable resource = new Whatever();
try {
    // whatever
}
finally {
    resource.Dispose();
}
using 的主要优点是:在离开 using 块时,它会自动处理对象的销毁,这样就不会忘记销毁对象,并且在异常情况下也可以进行清理。

简单规则:

  • 任何时候打开文件/数据库连接或创建需要任何类型的清理的类实例-都要在 using 块中进行。
  • 如果对象的生命周期应该扩展到方法范围之外-将其包装在一个类中,在该类中实现 IDisposable 接口,在构造函数中实例化资源,在 Dispose 中进行清理。

3
  • using语句允许程序员指定使用资源的对象何时释放它们。
  • 提供给using语句的对象必须实现IDisposable接口。
  • 该接口提供了Dispose方法,该方法应释放对象的资源。

以下是使用using语句的示例:

using System;
//Object of this class will be given to using hence IDisposable
class C : IDisposable        
{
    public void UseLimitedResource()
    {
        Console.WriteLine("Using limited resource...");
    }

    //Dispose() Method
    void IDisposable.Dispose()
    {
        Console.WriteLine("Disposing limited resource.");
    }
}

class Program
{
    static void Main()
    {
        using (C c = new C())  //Object of Class defined above
        {
            c.UseLimitedResource();
            //Object automatically disposed before closing.
        }                            
        Console.WriteLine("Now outside using statement.");
        Console.ReadLine();
    }
}

一个using语句可以在以下情况下被退出:
  • 到达using语句的结尾;或者
  • 如果在语句块结束之前控制权离开了语句块并抛出了异常。

哪种方法是正确的?

由于您说:

两个类出于实用性都是可处理的

因此,您的第二种方法是适当的,即:

using (MyClass myClass = new MyClass(params))
{
     myClass.name = "Steve";

     using (SecondClass myClassSecond = new SecondClass(params))
     {
          myClassSecond.name = "George";
          myClassSecond.msg = "Hello Man in the Yellow Hat";
     }
}

3

假设SecondClass确实是可处理的,您的第二个示例是正确的。如果不是,则第一个示例不正确,因为mySecondClass不会被处理。如果代码块控制可处理实例的生命周期,则应始终处理它。

顺便说一下,我更喜欢在同一代码块中处理多个对象的方式,因为我认为这样更易读。

using (MyClass myClass = new MyClass(params))
using (SecondClass myClassSecond = new SecondClass(params))     
{
     myClassSecond.name = "George";
     myClassSecond.msg = "Hello Man in the Yellow Hat";     
}

两个using语句共享相同的作用域,并按照声明的相反顺序进行Dispose。


这正是我寻找的,谢谢。我不确定将所有内容放在一个using块中是否会处理掉所有内容,还是每个项目都需要包装在自己的可处置气泡中。这两个项目确实是可以处置的,我忽略了这个信息。再次感谢。 - James Wilson

2

使用 using 块并不会自动处理实现了 IDisposable 接口的任何子对象。如果您想要处理内部的可处理对象,您必须将它们包装在 using 块中。但是,您有几种不同的选项。

您可以嵌套多个 using 块,它们按从内到外的顺序进行评估。虽然以下示例可行,但有更好的方法:

using (MyClass myClass = new MyClass(parameters))
{
     using (SecondClass myClassSecond = new SecondClass(parameters))
     {
          myClassSecond.name = "George";
          myClassSecond.msg = "Hello Man in the Yellow Hat";
     }
}

如果声明是连续的,并且您在其中不需要进行任何操作,则以下语法更为简洁:
using (MyClass myClass = new MyClass(parameters))
using (SecondClass myClassSecond = new SecondClass(parameters))
{
    myClassSecond.name = "George";
    myClassSecond.msg = "Hello Man in the Yellow Hat";
}

如果需要在声明之间执行某些操作,那么您后面的例子是正确的:
using (MyClass myClass = new MyClass(parameters))
{
     myClass.name = "Steve";

     using (SecondClass myClassSecond = new SecondClass(parameters))
     {
          myClassSecond.name = "George";
          myClassSecond.msg = "Hello Man in the Yellow Hat";
     }
}

0

我的经验法则是……如果它实现了IDisposable接口,我就使用using块。

总是安全第一。

回答你的问题,我会选择第二个选项。


0

0

using块是处理IDisposable对象的一种语法简单的方式。如果您理解using的作用,那么您应该知道如何使用它。

请参阅此问题,了解using块被翻译成什么: C#中“using”的用途


0

这取决于那些类是什么以及它们如何处理任何使用的资源。 using 语句基本上与 try/finally 块相同(没有 catch),后者在 finally 块中处理其资源(通过调用涉及对象的 .Dispose())。

所以,首先,如果问题中的类没有实现 IDisposable,那么这就是一个无关紧要的问题,在这种情况下,你不能在 using 块中使用它。如果它确实实现了 IDisposable,那么很有可能它之所以这样做是有原因的,当你完成使用时应该调用 .Dispose() 来对该对象进行清理。在这些情况下,最好将其包装在 using 块中以保证处理。 (嗯,“保证”就是 finally 块将被执行。这通常是情况,除非发生了更糟糕的事情。)


0

如果我创建的类使用了大量资源,或者我将其作为文件处理或网络资源的包装器,则我喜欢在这些类中实现IDisposable

在我使用的类对象中,如果涉及到打开文件、创建网络连接等操作,我认为使用using块进行调用非常重要。

有些开发人员会编写一个实现IDisposable的类,只是为了将代码放在更清晰的using块中,但我认为这滥用了创建可处理对象的原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接