用户 科科斯 回答了精彩的 C# 的隐藏特性 问题通过提及 using 关键词。你能详细说明一下吗?有什么用途 using?

有帮助吗?

解决方案

原因是 using 声明的目的是确保对象一旦超出范围就被处置,并且不需要显式代码来确保这种情况发生。

如在 理解 C# 中的“using”语句, ,.NET CLR 转换

using (MyResource myRes = new MyResource())
{
    myRes.DoSomething();
}

{ // Limits scope of myRes
    MyResource myRes= new MyResource();
    try
    {
        myRes.DoSomething();
    }
    finally
    {
        // Check for a null resource.
        if (myRes != null)
            // Call the object's Dispose method.
            ((IDisposable)myRes).Dispose();
    }
}

其他提示

因为很多人仍然这样做:

using (System.IO.StreamReader r = new System.IO.StreamReader(""))
using (System.IO.StreamReader r2 = new System.IO.StreamReader("")) {
   //code
}

我想很多人仍然不知道你可以这样做:

using (System.IO.StreamReader r = new System.IO.StreamReader(""), r2 = new System.IO.StreamReader("")) {
   //code
}

像这样的事情:

using (var conn = new SqlConnection("connection string"))
{
   conn.Open();

    // Execute SQL statement here on the connection you created
}

SqlConnection 将被关闭而不需要显式调用 .Close() 函数,这将会发生 即使抛出异常, ,无需 try/catch/finally.

using 可用于调用 IDisposable。它还可以用于别名类型。

using (SqlConnection cnn = new SqlConnection()) { /*code*/}
using f1 = System.Windows.Forms.Form;

使用,在某种意义上

using (var foo = new Bar())
{
  Baz();
}

实际上是 try/finally 块的简写。它相当于代码:

var foo = new Bar();
try
{
  Baz();
}
finally
{
  foo.Dispose();
}

当然,您会注意到,第一个片段比第二个片段简洁得多,而且即使抛出异常,您也可能需要执行多种操作来进行清理。因此,我们提出了一个称为 Scope 的类,它允许您在 Dispose 方法中执行任意代码。因此,举例来说,如果您有一个名为 IsWorking 的属性,并且在尝试执行操作后始终希望将其设置为 false,则可以这样做:

using (new Scope(() => IsWorking = false))
{
  IsWorking = true;
  MundaneYetDangerousWork();
}

您可以阅读有关我们的解决方案以及我们如何得出它的更多信息 这里.

我过去经常使用它来处理输入和输出流。您可以很好地嵌套它们,并且它可以消除您通常遇到的许多潜在问题(通过自动调用 dispose)。例如:

        using (FileStream fs = new FileStream("c:\file.txt", FileMode.Open))
        {
            using (BufferedStream bs = new BufferedStream(fs))
            {
                using (System.IO.StreamReader sr = new StreamReader(bs))
                {
                    string output = sr.ReadToEnd();
                }
            }
        }

微软文档指出 使用 具有双重功能(https://msdn.microsoft.com/en-us/library/zhdeatwt.aspx),两者都作为 指示 并在 声明. 。作为一个 陈述, ,正如在其他答案中指出的那样,该关键字基本上是语法糖,用于确定处置范围 I一次性 目的。作为一个 指示, ,它通常用于导入命名空间和类型。另外,作为指令,您可以创建 别名 对于命名空间和类型,正如《C# 5.0 In a Nutshell》一书中指出的:权威指南”(http://www.amazon.com/5-0-Nutshell-The-Definitive-Reference-ebook/dp/B008E6I1K8),约瑟夫和本阿尔巴哈里。一个例子:

namespace HelloWorld
{
    using AppFunc = Func<IDictionary<DateTime, string>, List<string>>;
    public class Startup
    {
        public static AppFunc OrderEvents() 
        {
            AppFunc appFunc = (IDictionary<DateTime, string> events) =>
            {
                if ((events != null) && (events.Count > 0))
                {
                    List<string> result = events.OrderBy(ev => ev.Key)
                        .Select(ev => ev.Value)
                        .ToList();
                    return result;
                }
                throw new ArgumentException("Event dictionary is null or empty.");
            };
            return appFunc;
        }
    }
}

这是明智的做法,因为滥用这种做法可能会损害代码的清晰度。DotNetPearls 中对 C# 别名有一个很好的解释,还提到了优点和缺点(http://www.dotnetperls.com/using-alias).

只是添加了一些令我惊讶的东西并没有出现。using 最有趣的功能(在我看来)是,无论你如何退出 using 块,它总是会释放该对象。这包括退货和例外。

using (var db = new DbContext())
{
    if(db.State == State.Closed) throw new Exception("Database connection is closed.");
    return db.Something.ToList();
}

抛出异常或返回列表并不重要。DbContext 对象将始终被释放。

using 的另一个重要用途是实例化模式对话框。

Using frm as new Form1

Form1.ShowDialog

' do stuff here

End Using

总之,当您使用实现了以下类型的局部变量时 IDisposable, 总是, ,无一例外地使用 using1.

如果您使用非本地 IDisposable 变量,那么 总是 实施 IDisposable 图案.

两个简单的规则,无一例外1. 。否则,防止资源泄漏对于 *ss 来说是一个真正的痛苦。


1):唯一的例外是——当您处理异常时。那么调用的代码可能会更少 Dispose 明确地在 finally 堵塞。

有趣的是,您还可以将 using/IDisposable 模式用于其他有趣的事情(例如 Rhino Mocks 使用它的方式的另一点)。基本上,您可以利用编译器将 总是 对“已用”对象调用 .Dispose。如果您在某个操作后需要发生一些事情......有明确开始和结束的事物...那么您可以简单地创建一个 IDisposable 类,在构造函数中启动操作,然后在 Dispose 方法中完成。

这允许您使用非常好的 using 语法来表示所述操作的显式开始和结束。这也是 System.Transactions 的工作原理。

您可以通过以下示例来使用别名命名空间:

using LegacyEntities = CompanyFoo.CoreLib.x86.VBComponents.CompanyObjects;

这被称为 使用别名指令 如您所见,如果您想在代码中显而易见,它可以用来隐藏长期的引用

LegacyEntities.Account

代替

CompanyFoo.CoreLib.x86.VBComponents.CompanyObjects.Account

或者简单地

Account   // It is not obvious this is a legacy entity

使用 ADO.NET 时,您可以将 keywork 用于连接对象或读取器对象等。这样,当代码块完成时,它将自动释放您的连接。

“using”也可以用来解决命名空间冲突。看 http://www.davidarno.org/c-howtos/aliases-overcoming-name-conflicts/ 我写了一篇关于这个主题的简短教程。

public class ClassA:IDisposable

{
   #region IDisposable Members        
    public void Dispose()
    {            
        GC.SuppressFinalize(this);
    }
    #endregion
}

public void fn_Data()

    {
     using (ClassA ObjectName = new ClassA())
            {
                //use objectName 
            }
    }

使用 当您有一个资源在使用后想要处置时使用。

例如,如果您分配了一个文件资源,并且只需要在一段代码中使用它来进行少量读取或写入,则使用有助于在完成后立即处理文件资源。

正在使用的资源需要实现 IDisposable 才能正常工作。

例子:

using (File file = new File (parameters))
{
    *code to do stuff with the file*
}

using 关键字定义对象的范围,然后在范围完成时释放该对象。例如。

using (Font font2 = new Font("Arial", 10.0f))
{
    // use font2
}

这里 有关 C# using 关键字的 MSDN 文章。

并不是说它非常重要,但使用也可以用于动态更改资源。是的,如前所述,是一次性的,但也许您不希望在其余执行过程中资源与其他资源不匹配。所以你想处理掉它,这样它就不会干扰其他地方。

感谢下面的评论,我将稍微清理一下这篇文章(我当时不应该使用“垃圾收集”这个词,抱歉):
当您使用 using 时,它将在 using 作用域末尾调用对象上的 Dispose() 方法。因此,您可以在 Dispose() 方法中包含大量出色的清理代码。
这里有一个要点,希望可能会得到这个未标记的:如果您实现 IDisposable,请确保在 Dispose() 实现中调用 GC.SuppressFinalize(),否则自动垃圾收集将尝试在某个时刻出现并最终确定它,如果您这样做,这至少会浪费资源已经 Dispose()d 了。

立即处置该对象的合理使用的另一个例子:

using (IDataReader myReader = DataFunctions.ExecuteReader(CommandType.Text, sql.ToString(), dp.Parameters, myConnectionString)) 
{
    while (myReader.Read()) 
    {
        MyObject theObject = new MyObject();
        theObject.PublicProperty = myReader.GetString(0);
        myCollection.Add(theObject);
    }
}

大括号之外的所有内容都已被丢弃,因此如果您不使用对象,最好将其丢弃。之所以如此,是因为如果您有一个 SqlDataAdapter 对象,并且在应用程序生命周期中仅使用它一次,并且您只填充一个数据集并且不再需要它,则可以使用以下代码:

using(SqlDataAdapter adapter_object = new SqlDataAdapter(sql_command_parameter))
{
   // do stuff
} // here adapter_object is disposed automatically

using 语句提供了一种正确使用 IDisposable 对象的便捷机制。通常,当您使用 IDisposable 对象时,应在 using 语句中声明并实例化它。using 语句以正确的方式调用对象上的 Dispose 方法,并且(当您如前面所示使用它时)它还会导致对象本身在调用 Dispose 时超出范围。在 using 块中,对象是只读的,不能修改或重新分配。

这来自: 这里

对我来说,“using”这个名字有点令人困惑,因为它可以是导入命名空间或语句(如此处讨论的)以进行错误处理的指令。

错误处理的不同名称会很好,而且也许是一个更明显的名称。

它还可用于创建示例范围:

class LoggerScope:IDisposable {
   static ThreadLocal<LoggerScope> threadScope = 
        new ThreadLocal<LoggerScope>();
   private LoggerScope previous;

   public static LoggerScope Current=> threadScope.Value;

   public bool WithTime{get;}

   public LoggerScope(bool withTime){
       previous = threadScope.Value;
       threadScope.Value = this;
       WithTime=withTime;
   }

   public void Dispose(){
       threadScope.Value = previous;
   }
}


class Program {
   public static void Main(params string[] args){
       new Program().Run();
   }

   public void Run(){
      log("something happend!");
      using(new LoggerScope(false)){
          log("the quick brown fox jumps over the lazy dog!");
          using(new LoggerScope(true)){
              log("nested scope!");
          }
      }
   }

   void log(string message){
      if(LoggerScope.Current!=null){
          Console.WriteLine(message);
          if(LoggerScope.Current.WithTime){
             Console.WriteLine(DateTime.Now);
          }
      }
   }

}

using 语句告诉 .NET 在不再需要时释放 using 块中指定的对象。因此,您应该对需要清理的类(例如 System.IO 类型)使用“using”块。

C#中using关键字有两种用法,如下所示。

  1. 作为指令

通常我们使用 using 关键字在代码隐藏和类文件中添加命名空间。然后它使当前页面中的所有类、接口和抽象类及其方法和属性都可用。

前任:

using System.IO;  
  1. 作为声明

这是在 C# 中使用 using 关键字的另一种方法。它在提高垃圾收集性能方面发挥着至关重要的作用。using 语句确保即使在创建对象、调用方法、属性等时发生异常,Dispose() 也会被调用。Dispose() 是 IDisposable 接口中提供的一种方法,有助于实现自定义垃圾收集。换句话说,如果我正在执行一些数据库操作(插入、更新、删除),但不知何故发生异常,那么这里的 using 语句会自动关闭连接。无需显式调用连接 Close() 方法。

另一个重要因素是它有助于连接池。.NET 中的连接池有助于消除多次关闭数据库连接的情况。它将连接对象发送到池以供将来使用(下一次数据库调用)。下次从应用程序调用数据库连接时,连接池将获取池中可用的对象。因此它有助于提高应用程序的性能。因此,当我们使用 using 语句时,控制器会自动将对象发送到连接池,无需显式调用 Close() 和 Dispose() 方法。

您可以通过使用 try-catch 块执行与 using 语句相同的操作,并显式调用 finally 块内的 Dispose()。但 using 语句会自动进行调用,使代码更干净、更优雅。在 using 块中,对象是只读的,不能修改或重新分配。

前任:

    string connString = "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;";  

using (SqlConnection conn = new SqlConnection(connString))  
{  
      SqlCommand cmd = conn.CreateCommand();  
      cmd.CommandText = "SELECT CustomerId, CompanyName FROM Customers";  
      conn.Open();  
      using (SqlDataReader dr = cmd.ExecuteReader())  
      {  
         while (dr.Read())  
         Console.WriteLine("{0}\t{1}", dr.GetString(0), dr.GetString(1));  
      }  
}  

在前面的代码中,我没有关闭任何连接,它会自动关闭。由于 using 语句(using (SqlConnection conn = new SqlConnection(connString)),using 语句将自动调用 conn.Close() ,对于 SqlDataReader 对象也是如此。而且如果发生任何异常,它会自动关闭连接。

欲了解更多信息--> https://www.c-sharpcorner.com/UploadFile/manas1/usage-and-importance-of-using-in-C-Sharp472/

Rhino Mocks 记录回放语法 有趣地利用了 using.

用作语句自动调用在指定对象上的处置。该对象必须实现 IDisposable 接口。只要它们的类型相同,就可以在一个语句中使用多个对象。

CLR 将您的代码转换为 MSIL。using 语句被转换为 try 和finally 块。这就是 using 语句在 IL 中的表示方式。using 语句被翻译成三个部分:获取、使用和处置。首先获取资源,然后将其使用情况包含在带有finally 子句的try 语句中。然后该对象在finally 子句中被释放。

using 子句用于定义特定变量的范围。例如:

     Using(SqlConnection conn=new SqlConnection(ConnectionString)
            {
                Conn.Open()
            // Execute sql statements here.
           // You do not have to close the connection explicitly here as "USING" will close the connection once the object Conn becomes out of the defined scope.
            }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top