【问题标题】:What is the C# Using block and why should I use it? [duplicate]什么是 C# Using 块,我为什么要使用它? [复制]
【发布时间】:2010-09-17 18:03:38
【问题描述】:

C# 中Using 块的用途是什么?它与局部变量有何不同?

【问题讨论】:

    标签: c# .net syntax using using-statement


    【解决方案1】:

    如果该类型实现了 IDisposable,它会自动释放该类型。

    给定:

    public class SomeDisposableType : IDisposable
    {
       ...implmentation details...
    }
    

    这些是等价的:

    SomeDisposableType t = new SomeDisposableType();
    try {
        OperateOnType(t);
    }
    finally {
        if (t != null) {
            ((IDisposable)t).Dispose();
        }
    }
    
    using (SomeDisposableType u = new SomeDisposableType()) {
        OperateOnType(u);
    }
    

    第二个更容易阅读和维护。


    从 C# 8 开始,有一个 new syntax for using 可以使代码更具可读性:

    using var x = new SomeDisposableType();
    

    它没有自己的{ } 块,使用范围是从声明点到声明它的块的末尾。这意味着您可以避免以下内容:

    string x = null;
    using(var someReader = ...)
    {
      x = someReader.Read();
    }
    

    还有这个:

    using var someReader = ...;
    string x = someReader.Read();
    

    【讨论】:

    • 请注意,通常 finally 块会在调用 Dispose 之前检查是否为空。调用构造函数时并不重要,但是...
    • 如果你在 using 块之外声明变量,然后在 using 语句中创建一个新实例,它可能不会释放该项目。
    • 因此,一旦上下文完成,using 语句将自动处理对象,那么我们应该何时在实现 IDisposable 的类型上使用 using 语句?哪些类型必须实现该接口,是否有任何经验法则或者我必须单独检查每种类型?
    • 作为迂腐的,你需要在你的第二个代码块周围用花括号来反映有限的范围。
    • 注意: 注意将using 块与HttpClient() 一起使用!见this article
    【解决方案2】:
    using (B a = new B())
    {
       DoSomethingWith(a);
    }
    

    等价于

    B a = new B();
    try
    {
      DoSomethingWith(a);
    }
    finally
    {
       ((IDisposable)a).Dispose();
    }
    

    【讨论】:

      【解决方案3】:

      using 语句用于处理 C# 中实现IDisposable 接口的对象。

      IDisposable 接口有一个名为Dispose 的公共方法,用于处理对象。当我们使用 using 语句时,我们不需要在代码中显式地处理对象,由 using 语句处理。

      using (SqlConnection conn = new SqlConnection())
      {
      
      }
      

      当我们使用上面的代码块时,内部代码是这样生成的:

      SqlConnection conn = new SqlConnection() 
      try
      {
      
      }
      finally
      {
          // calls the dispose method of the conn object
      }
      

      更多详情请阅读:Understanding the 'using' statement in C#

      【讨论】:

        【解决方案4】:

        还要注意,通过using 实例化的对象在 using 块中是只读的。参考官方C#参考here

        【讨论】:

          【解决方案5】:

          Using 在离开using 块后调用Dispose(),即使代码抛出异常。

          因此,您通常将using 用于需要在它们之后进行清理的类,例如 IO。

          所以,这个 using 块:

          using (MyClass mine = new MyClass())
          {
            mine.Action();
          }
          

          会做同样的事情:

          MyClass mine = new MyClass();
          try
          {
            mine.Action();
          }
          finally
          {
            if (mine != null)
              mine.Dispose();
          }
          

          使用using 更短且更易于阅读。

          【讨论】:

          • 是否需要空检查?在“new MyClass()”之后我的怎么可能是空的;我唯一能看到的是 OutOfMemoryException 但在这种情况下它甚至不应该进入 try 块吗?编辑:你可能写这个来显示使用时通常会做什么。在 using 内部,除了新的构造函数调用之外,可能还有其他东西(例如:返回 null 的方法调用)
          • 好吧,除了mine.Action(),你还可以做其他事情。诸如mine=null 之类的东西。不使用 mine 可以设置为 try/catch 中的任何内容
          【解决方案6】:

          using语句获取一个或多个资源,执行一个语句,然后释放资源。

          【讨论】:

            【解决方案7】:

            它实际上只是一些语法糖,不需要您对实现 IDisposable 的成员显式调用 Dispose。

            【讨论】:

            • 这不是最好的短语吗? “句法糖”,我在海边买了一堆贝壳后,说的还不够。
            【解决方案8】:

            来自 MSDN:

            C#,通过 .NET Framework 通用 语言运行时 (CLR),自动 释放用于存储的内存 不再需要的对象。 内存的释放是 非确定性的;内存被释放 每当 CLR 决定执行 垃圾收集。然而,它是 通常最好发布有限 资源,例如文件句柄和 网络连接一样快 可能的。

            using 语句允许 程序员指定何时对象 使用资源应该释放 他们。提供给使用对象 声明必须执行 IDisposable 接口。这个界面 提供 Dispose 方法,该方法 应该释放对象的资源。

            换句话说,using 语句告诉 .NET 在不再需要时释放 using 块中指定的对象。

            【讨论】:

            • 这给出了使用“using”的基本原理,而@plinth 显示了它的实际作用。
            • 确实如此。这就是“C# 中 Using 块的目的是什么?”的答案
            【解决方案9】:

            将代码放在 using 块中可确保在控制离开该块时立即释放对象(尽管不一定收集)。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-04-24
              • 2010-11-01
              • 2019-08-22
              • 1970-01-01
              • 2017-01-10
              • 2011-02-21
              相关资源
              最近更新 更多