it-swarm-vi.tech

Việc sử dụng "sử dụng" trong C # là gì

Người dùng kokos đã trả lời câu hỏi tuyệt vời Các tính năng ẩn của C # bằng cách đề cập đến từ khóa using. bạn có thể giải thích về điều đó không? Việc sử dụng using là gì?

289
ubermonkey

Lý do cho câu lệnh using là để đảm bảo rằng đối tượng được xử lý ngay khi nó ra khỏi phạm vi và nó không yêu cầu mã rõ ràng để đảm bảo rằng điều này xảy ra.

Như trong Hiểu câu lệnh 'bằng cách sử dụng' trong C #, .NET CLR chuyển đổi

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

đến

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

Vì nhiều người vẫn làm:

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

Tôi đoán rất nhiều người vẫn không biết rằng bạn có thể làm:

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

Những thứ như thế này:

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

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

SqlConnection này sẽ bị đóng mà không cần gọi hàm .Close() một cách rõ ràng và điều này sẽ xảy ra ngay cả khi một ngoại lệ được ném, mà không cần try/catch/finally.

95
Joel Coehoorn

sử dụng có thể được sử dụng để gọi IDis Dùng. Nó cũng có thể được sử dụng để các loại bí danh.

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

sử dụng, theo nghĩa

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

Thực sự là tốc ký cho một khối thử/cuối cùng. Nó tương đương với mã:

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

Tất nhiên, bạn sẽ lưu ý rằng đoạn mã đầu tiên ngắn gọn hơn đoạn thứ hai và cũng có nhiều loại mà bạn có thể muốn làm như dọn dẹp ngay cả khi ném ngoại lệ. Vì điều này, chúng tôi đã đưa ra một lớp mà chúng tôi gọi là Phạm vi cho phép bạn thực thi mã tùy ý trong phương thức Vứt bỏ. Vì vậy, ví dụ, nếu bạn có một thuộc tính có tên IsWorking mà bạn luôn muốn đặt thành false sau khi thử thực hiện một thao tác, bạn sẽ làm như thế này:

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

Bạn có thể đọc thêm về giải pháp của chúng tôi và cách chúng tôi bắt nguồn nó tại đây .

21
David Mitchell

Tài liệu của Microsoft tuyên bố rằng bằng cách sử dụng có chức năng kép ( https://msdn.Microsoft.com/en-us/l Library/zadeatwt. aspx ), cả dưới dạng một lệnh và trong câu lệnh . Như một câu lệnh , như đã được chỉ ra ở đây trong các câu trả lời khác, từ khóa về cơ bản là cú pháp để xác định một phạm vi để loại bỏ IDis Dùng đối tượng. Là một lệnh , nó thường được sử dụng để nhập các không gian tên và kiểu. Cũng như một lệnh, bạn có thể tạo bí danh cho các không gian tên và loại, như được chỉ ra trong cuốn sách "C # 5.0 In a Nutshell: The Definitive Guide" ( http: // www <azon.com/5-0-Nutshell-The-Defitive-Reperence-ebook/dp/B008E6I1K8 ), bởi Joseph và Ben Albahari. Một ví dụ:

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

Đây là một cái gì đó để áp dụng một cách khôn ngoan, vì việc lạm dụng thực hành này có thể làm tổn thương sự rõ ràng của mã của một người. Có một lời giải thích hay về các bí danh C #, cũng đề cập đến ưu và nhược điểm, trong DotNetPearls ( http://www.dotnetperls.com/USE-alias ).

10
Aureliano Buendia

Tôi đã sử dụng nó rất nhiều trong quá khứ để làm việc với các luồng đầu vào và đầu ra. Bạn có thể lồng chúng độc đáo và nó sẽ loại bỏ rất nhiều vấn đề tiềm ẩn mà bạn thường gặp phải (bằng cách tự động gọi xử lý). Ví dụ:

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

Chỉ cần thêm một chút gì đó mà tôi đã ngạc nhiên đã không đến. Tính năng thú vị nhất của việc sử dụng (theo ý kiến ​​của tôi) là không có vấn đề gì về cách bạn thoát khỏi khối sử dụng, nó sẽ luôn loại bỏ đối tượng. Điều này bao gồm lợi nhuận và ngoại lệ.

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

Không có vấn đề gì nếu ngoại lệ được ném hoặc danh sách được trả về. Đối tượng DbContext sẽ luôn được xử lý.

8
Pluc

Một cách sử dụng tuyệt vời khác là sử dụng khi khởi tạo hộp thoại theo chế độ.

Using frm as new Form1

Form1.ShowDialog

' do stuff here

End Using
6
Lucas

Tóm lại, khi bạn sử dụng biến cục bộ của loại thực hiện IDisposablename__, luôn luôn , không có ngoại lệ, hãy sử dụng usingname__1.

Nếu bạn sử dụng các biến IDisposablekhông cục bộ, thì luôn luôn triển khai mẫu IDisposableNAME_ .

Hai quy tắc đơn giản, không ngoại lệ1. Ngăn chặn rò rỉ tài nguyên nếu không là một nỗi đau thực sự trong * ss.


1): Ngoại lệ duy nhất là - khi bạn xử lý ngoại lệ. Sau đó, có thể gọi mã Disposemột cách rõ ràng trong khối finallyname__.

5
Konrad Rudolph

Bạn có thể sử dụng không gian tên bí danh bằng ví dụ sau:

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

Điều này được gọi là sử dụng chỉ thị bí danh như bạn có thể thấy, nó có thể được sử dụng để ẩn các tham chiếu dài dòng nếu bạn muốn làm cho nó rõ ràng trong mã của bạn những gì bạn đang đề cập đến, ví dụ:.

LegacyEntities.Account

thay vì

CompanyFoo.CoreLib.x86.VBComponents.CompanyObjects.Account

hoặc đơn giản

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

Thật thú vị, bạn cũng có thể sử dụng mẫu sử dụng/IDis Dùng cho những thứ thú vị khác (chẳng hạn như điểm khác của cách Rhino Mocks sử dụng nó). Về cơ bản, bạn có thể tận dụng thực tế là trình biên dịch sẽ luôn luôn gọi .Dispose trên đối tượng "đã sử dụng". Nếu bạn có một cái gì đó cần phải xảy ra sau một hoạt động nhất định ... một cái gì đó có bắt đầu và kết thúc rõ ràng ... thì bạn có thể chỉ cần tạo một lớp IDis Dùng để bắt đầu hoạt động trong hàm tạo, và sau đó kết thúc trong phương thức Vứt bỏ.

Điều này cho phép bạn sử dụng cú pháp sử dụng Nice thực sự để biểu thị sự bắt đầu và kết thúc rõ ràng của thao tác đã nói. Đây cũng là cách các công cụ System.Transilities hoạt động.

4
Joel Martinez
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 
            }
    }
3
Shiraj Momin

Khi sử dụng ADO.NET, bạn có thể sử dụng keywork cho những thứ như đối tượng kết nối hoặc đối tượng người đọc. Theo cách đó, khi khối mã hoàn thành, nó sẽ tự động loại bỏ kết nối của bạn.

3
Joseph Daigle

"Sử dụng" cũng có thể được sử dụng để giải quyết xung đột không gian tên. Xem http://www.davidarno.org/c-howtos/aliases-overasing-name-conflicts/ để xem hướng dẫn ngắn tôi đã viết về chủ đề này.

3
David Arno

Câu lệnh sử dụng yêu cầu .NET giải phóng đối tượng được chỉ định trong khối sử dụng một khi nó không còn cần thiết nữa. Vì vậy, bạn nên sử dụng khối 'bằng cách sử dụng' cho các lớp yêu cầu dọn dẹp sau chúng, như Kiểu System.IO.

1
deepak samantaray

Có hai cách sử dụng từ khóa trong C # như sau.

  1. như một chỉ thị

Nói chung, chúng tôi sử dụng từ khóa để thêm các không gian tên trong các tệp mã phía sau và lớp. Sau đó, nó làm cho tất cả các lớp, giao diện và các lớp trừu tượng cũng như các phương thức và thuộc tính của chúng trong trang hiện tại.

Vd

using System.IO;  
  1. như một tuyên bố

Đây là một cách khác để sử dụng từ khóa sử dụng trong C #. Nó đóng một vai trò quan trọng trong việc cải thiện hiệu suất trong Bộ sưu tập rác. Câu lệnh sử dụng đảm bảo rằng Dispose () được gọi ngay cả khi có ngoại lệ xảy ra khi bạn đang tạo đối tượng và gọi phương thức, thuộc tính, v.v. Vứt bỏ () là một phương thức có trong giao diện IDis Dùng để thực hiện Bộ sưu tập Rác tùy chỉnh. Nói cách khác, nếu tôi đang thực hiện một số thao tác cơ sở dữ liệu (Chèn, Cập nhật, Xóa) nhưng bằng cách nào đó, một ngoại lệ xảy ra thì ở đây câu lệnh sử dụng sẽ tự động đóng kết nối. Không cần gọi phương thức Close () một cách rõ ràng.

Một yếu tố quan trọng khác là nó giúp kết nối Pooling. Kết nối Pooling trong .NET giúp loại bỏ việc đóng kết nối cơ sở dữ liệu nhiều lần. Nó sẽ gửi đối tượng kết nối đến một nhóm để sử dụng trong tương lai (cuộc gọi cơ sở dữ liệu tiếp theo). Lần sau, một kết nối cơ sở dữ liệu được gọi từ ứng dụng của bạn, nhóm kết nối sẽ tìm nạp các đối tượng có sẵn trong nhóm. Vì vậy, nó giúp cải thiện hiệu suất của ứng dụng. Vì vậy, khi chúng ta sử dụng câu lệnh sử dụng, bộ điều khiển sẽ tự động gửi đối tượng đến nhóm kết nối, không cần phải gọi các phương thức Close () và Dispose () một cách rõ ràng.

Bạn có thể làm tương tự như những gì câu lệnh đang sử dụng đang làm bằng cách sử dụng khối try-Catch và gọi Dispose () bên trong khối cuối cùng một cách rõ ràng. Nhưng câu lệnh sử dụng thực hiện các cuộc gọi tự động để làm cho mã sạch hơn và thanh lịch hơn. Trong khối sử dụng, đối tượng chỉ đọc và không thể sửa đổi hoặc gán lại.

Vd

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

Trong mã trước tôi không đóng bất kỳ kết nối nào, nó sẽ tự động đóng. Câu lệnh sử dụng sẽ tự động gọi Conn.Close () do câu lệnh sử dụng (bằng cách sử dụng (SqlConnection Conn = new SqlConnection (ConnString)) và tương tự cho một đối tượng SqlDataReader. Và nếu có bất kỳ ngoại lệ nào xảy ra, nó sẽ tự động đóng kết nối.

Để biết thêm thông tin -> https://www.c-sharpcorner.com/UploadFile/manas1/usage-and-importance-of-USE-in-C-Sharp472/

1
Chamila Maddumage

Đối với tôi, tên "bằng cách sử dụng" hơi khó hiểu, bởi vì đây có thể là một lệnh để nhập một Không gian tên hoặc một câu lệnh (như câu lệnh được thảo luận ở đây) để xử lý lỗi.

Một tên khác để xử lý lỗi sẽ là Nice và có thể là một tên rõ ràng hơn.

1
Seb

Nó cũng có thể được sử dụng để tạo phạm vi cho Ví dụ:

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

}
1
Siamand Maroufi

Không phải là nó cực kỳ quan trọng, nhưng việc sử dụng cũng có thể được sử dụng để thay đổi tài nguyên một cách nhanh chóng. Có dùng một lần như đã đề cập trước đó, nhưng có lẽ cụ thể là bạn không muốn các tài nguyên mà chúng không khớp với các tài nguyên khác trong suốt thời gian thực hiện. Vì vậy, bạn muốn loại bỏ nó để nó không can thiệp vào nơi khác.

1
Scot McPherson

Cú pháp phát lại bản ghi Rhino Mocks sử dụng using thú vị.

1
Gilligan

Câu lệnh sử dụng cung cấp một cơ chế tiện lợi để sử dụng chính xác các đối tượng IDis Dùng. Theo quy định, khi bạn sử dụng một đối tượng IDis Dùng một lần, bạn nên khai báo và khởi tạo nó trong một câu lệnh sử dụng. Câu lệnh sử dụng gọi phương thức Vứt bỏ trên đối tượng theo đúng cách và (khi bạn sử dụng nó như được hiển thị trước đó), nó cũng làm cho chính đối tượng đi ra khỏi phạm vi ngay khi được gọi. Trong khối sử dụng, đối tượng chỉ đọc và không thể sửa đổi hoặc gán lại.

Điều này đến từ: tại đây

1
snowell

Nhờ các bình luận bên dưới, tôi sẽ dọn sạch bài đăng này một chút (Tôi không nên sử dụng các từ 'bộ sưu tập rác' vào thời điểm đó, xin lỗi):
[.___.] Khi bạn sử dụng bằng cách sử dụng, nó sẽ gọi phương thức Dispose () trên đối tượng ở cuối phạm vi sử dụng. Vì vậy, bạn có thể có khá nhiều mã dọn dẹp tuyệt vời trong phương thức Dispose () của mình.
[.___ và Hoàn thiện nó tại một số điểm, ít nhất sẽ gây lãng phí tài nguyên nếu bạn đã vứt bỏ () d của nó.

1
Grank

Tất cả mọi thứ bên ngoài dấu ngoặc nhọn đều được xử lý, vì vậy thật tuyệt vời khi loại bỏ các đối tượng của bạn nếu bạn không sử dụng chúng. Điều này là như vậy bởi vì nếu bạn có một đối tượng SqlDataAd CHƯƠNG và bạn chỉ sử dụng nó một lần trong vòng đời ứng dụng và bạn chỉ điền vào một tập dữ liệu và bạn không cần nó nữa, bạn có thể sử dụng mã:

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

Từ khóa sử dụng xác định phạm vi cho đối tượng và sau đó loại bỏ đối tượng khi phạm vi hoàn thành. Ví dụ.

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

Xem tại đây để biết bài viết MSDN về từ khóa C #.

1
David Basarab

Một ví dụ khác về việc sử dụng hợp lý trong đó đối tượng được xử lý ngay lập tứ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);
    }
}
1
Brendan Kendrick

bằng cách sử dụng được sử dụng khi bạn có tài nguyên mà bạn muốn xử lý sau khi được sử dụng.

Chẳng hạn, nếu bạn phân bổ tài nguyên Tệp và chỉ cần sử dụng nó trong một phần mã để đọc hoặc viết, sử dụng rất hữu ích cho việc xử lý tài nguyên Tệp ngay khi bạn hoàn thành.

Tài nguyên đang được sử dụng cần triển khai IDis Dùng để hoạt động đúng.

Thí dụ:

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