用户kokos通过使用关键字回答了c#的隐藏特性问题。你能详细说明一下吗?使用的用途是什么?


当前回答

在c#中using关键字有以下两种用法。

As a directive Generally we use the using keyword to add namespaces in code-behind and class files. Then it makes available all the classes, interfaces and abstract classes and their methods and properties in the current page. Example: using System.IO; As a statement This is another way to use the using keyword in C#. It plays a vital role in improving performance in garbage collection. The using statement ensures that Dispose() is called even if an exception occurs when you are creating objects and calling methods, properties and so on. Dispose() is a method that is present in the IDisposable interface that helps to implement custom garbage collection. In other words if I am doing some database operation (Insert, Update, Delete) but somehow an exception occurs then here the using statement closes the connection automatically. No need to call the connection Close() method explicitly. Another important factor is that it helps in Connection Pooling. Connection Pooling in .NET helps to eliminate the closing of a database connection multiple times. It sends the connection object to a pool for future use (next database call). The next time a database connection is called from your application the connection pool fetches the objects available in the pool. So it helps to improve the performance of the application. So when we use the using statement the controller sends the object to the connection pool automatically, there is no need to call the Close() and Dispose() methods explicitly. You can do the same as what the using statement is doing by using try-catch block and call the Dispose() inside the finally block explicitly. But the using statement does the calls automatically to make the code cleaner and more elegant. Within the using block, the object is read-only and cannot be modified or reassigned. Example: 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对象也是如此。并且如果发生任何异常,它将自动关闭连接。

有关更多信息,请参见在c#中使用的用法和重要性。

其他回答

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

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);
    }
}

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

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

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 goes out of the defined scope.
}

使用using语句的原因是为了确保对象一旦超出作用域就会被释放,并且不需要显式代码来确保发生这种情况。

正如在理解c#中的“using”语句(codeproject)和使用实现IDisposable的对象(microsoft)中,c#编译器转换

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

to

{ // 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();
    }
}

c# 8引入了一个新的语法,命名为“using declarations”:

using声明是一个前面有using关键字的变量声明。它告诉编译器,所声明的变量应该在封闭作用域的末尾被处理。

所以上面的等效代码是:

using var myRes = new MyResource();
myRes.DoSomething();

当控制离开包含范围(通常是一个方法,但也可以是一个代码块)时,myRes将被释放。

使用,在某种意义上

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();
}

你可以在这里阅读更多关于我们的解以及我们是如何推导它的。