2010-10-03 35 views
7

Nếu một đối tượng nhận IDisposable trong C# ai có thể viếtCó phải 'đang sử dụng' từ khóa C# không?

using(DisposableFoo foo = new DisposableFoo()) 

Tôi luôn tự hỏi tại sao các using trông giống như một C# từ khóa, nhưng đòi hỏi một giao diện được định nghĩa trong khuôn khổ Net. Là using một từ khoá (trong ngữ cảnh này, rõ ràng là để xác định nhập khẩu thư viện của bạn), hoặc có Microsoft quá tải nó sử dụng trong Visual Studio/.Net framework? Tôi đã không mong đợi một từ khóa C# phụ thuộc vào một thư viện.

+6

Tôi không thấy vấn đề với từ khóa yêu cầu "đối số" của nó để triển khai giao diện. 'foreach' cũng là một từ khóa và yêu cầu bộ sưu tập là' IEnumerable'. – sepp2k

+3

@ sepp2k - điểm dành cho người đi bộ: bạn * KHÔNG * cần IEnumerable cho foreach. –

+0

@Marc Gravell: Ý bạn là gì? theo một liên kết msdn nó nói "System.Collections.IEnumerable hoặc System.Collections.Generic.IEnumerable " http://msdn.microsoft.com/en-us/library/ttw7t8t6.aspx –

Trả lời

6

Vâng, đó là từ khóa. Ngôn ngữ C# dựa trên khuôn khổ để triển khai nhiều từ khóa.

Các từ khóa khác dựa trên khuôn khổ là dành cho exmaple foreach (sử dụng IEnumerable) và cú pháp LINQ (khi được sử dụng với LINQ to Objects yêu cầu thư viện System.Linq).

Ngay cả các từ khóa như intstring dựa trên các loại System.Int32System.String trong khuôn khổ.

+3

Thực tế việc sử dụng không phổ biến * vì * nó yêu cầu một giao diện. Bạn có thể sử dụng foreach mà không cần IEnumerable, và LINQ mà không có bất kỳ thư viện đặc biệt nào (thậm chí nó không cần các phương thức mở rộng) –

+1

@Mark Gravell: Tôi nghĩ rằng nó thực sự là không phổ biến vì nó sử dụng một kiểu gõ vịt không có tính cách đối với C# , yêu cầu thực hiện IEnumerable, nhưng không yêu cầu giao diện thực tế. Tôi sẽ làm rõ rằng đó là LINQ to Objects yêu cầu thư viện System.Linq. – Guffa

+0

@guffa LINQ có nghĩa là cú pháp truy vấn ngôn ngữ không yêu cầu bất kỳ thư viện cụ thể nào. Tôi có thể viết một ứng dụng giao diện điều khiển C# 3/.net 2.0 sử dụng cú pháp truy vấn LINQ. –

1

Tôi nghĩ rằng sử dụng là một từ khóa mà chủ yếu làm cho mã của bạn

B b=new B();//can get resource outside using statement but will dispose inside of it 
using(A a=new A(),b,C c=new C() //A,B,C are variable of types that implement IDisposable){ 
SomeCode//Some code to execute 
} 

vào

B b= new B(); 
try{ 
A a= new A(); 
C c= new C();//B isn't here since 

SomeCode//execute the code 

}finallly{ 
a.Dispose();//The reason A,B,C need to implement IDisposable 
b.Dispose();//is so the compiler can make sure that they can call Dispose() 
c.Dispose(); 
} 

Các bit quan trọng với lý do tại sao IDisposable được sử dụng là vì C# được gõ mạnh, đằng sau hậu trường gọi của nó Vứt bỏ(), và thực hiện IDisposable cho trình biên dịch nó có thể.

Tương tự như cách foreach với IEnumerable và IEnumerator (gọi GetEnumerator(), Current(), MoveNext() mặc dù tôi nghĩ rằng nó không làm điều này với mảng chỉ các lớp sưu tập).

+0

Tôi nghĩ rằng việc sử dụng (A = a mới A(), C c = new C()) sẽ không hoạt động. Trình biên dịch trả về thông báo này: "Không thể sử dụng nhiều loại trong câu lệnh for, using, hoặc declaration". Tôi biết nó chỉ là một chi tiết của những gì bạn đã giải thích, nhưng không ai đề cập đến nó và đó là những gì tôi đang tìm kiếm. – Alpha

8

đó là cấu trúc từ khóa yêu cầu IDisposable vì nó hoạt động trên phương thức Vứt bỏ của đối tượng. Nó không quá xa để có một từ khóa sử dụng một loại. Nếu là một từ khóa và nó đòi hỏi một loại điều kiện (IE: Boolean).

4

C# được gắn cổ tích chặt chẽ với CLI và thông số ngôn ngữ sử dụng số tối thiểu tính năng thời gian chạy tối thiểu. IDisposable cho "sử dụng" thực sự là cứng nhắc bất thường, như trong hầu hết các trường hợp (ví dụ "foreach", LINQ, vv) có hỗ trợ cả khi có và không có thời gian chạy cụ thể.

Tuy nhiên, vì cấu trúc IDisposable/using là khóa để .NET Tôi nghi ngờ bạn có thể tạo CLI tối thiểu (nhưng hợp pháp) mà không có nó, vì vậy nó không thực sự là một vấn đề để đề cập đến nó trong spec ngôn ngữ.

Những thứ khác mà buộc với các loại cụ thể:

  • nối chuỗi (+ vs chuỗi.Concat)
  • phương pháp khuyến nông
  • generic mới()
  • [Serializable] (bản đồ đến một lá cờ IL, không phải là một thuộc tính)
  • foreach (nhưng có thể được sử dụng mà không cần bất kỳ các giao diện)
  • lõi loại cơ sở (Enum mảng Object ValueType Đại biểu)
  • biên dịch biểu hiện cây (nhưng cũng không được mô tả trong spec)

Etc

2

Có, có sự liên kết chắc chắn giữa ngôn ngữ và các bộ phận hỗ trợ trong khung công tác .NET. Cho đến nay điều quan trọng nhất là mscorlib.dll, trang chủ cho khai báo giao diện System.IDisposable. Điều quan trọng là nó thậm chí không được liệt kê trong nút Tham chiếu của dự án C# của bạn. Trình biên dịch C# giả sử nó luôn luôn cần thiết và sẽ tự tìm nó, trừ khi bạn sử dụng tùy chọn biên dịch đặc biệt/nostdlib.

ví dụ khác về yếu tố cú pháp đòi hỏi nó:

  • mảng [], đòi hỏi System.Array
  • [thuộc tính], đòi hỏi System.Attribute
  • bắt, đòi hỏi System.Exception
  • đại biểu, yêu cầu System.MulticastDelegate
  • loại ?, yêu cầu System.Nullable <>
  • thông số, r equires System.ParamArrayAttribute
  • typeof, đòi hỏi System.Type

Có khớp nối giữa tất cả các loại cơ bản và các tuyên bố tương ứng của họ trong mscorlib (như Int32, String, Object, ValueType vv).

Ví dụ sau là cú pháp hiểu LINQ truy vấn, yêu cầu System.Core.dll và từ khóa động, yêu cầu Microsoft.CSharp.dll. Những ví dụ này không có nghĩa là đầy đủ. Điều này là bình thường, thậm chí C trình biên dịch giả định rằng một thư viện thời gian chạy có sẵn với nguyên thủy như memset() và ldiv().

1

using là từ khóa C# hoạt động như một cú pháp-đường để xử lý các đối tượng có thể định dạng được. Theo MSDN

sử dụng khối Xác định phạm vi, bên ngoài một đối tượng hoặc vật thể sẽ được xử lý.

Tuyên bố sử dụng cho phép lập trình viên chỉ định khi nào các đối tượng sử dụng tài nguyên sẽ giải phóng chúng. Đối tượng được cung cấp cho câu lệnh using phải triển khai giao diện IDisposable. Giao diện này cung cấp phương thức Vứt bỏ, nên giải phóng tài nguyên của đối tượng.

Đáng ngạc nhiên ngay cả MSDN cũng không làm rõ cách điều này xảy ra dưới mui xe. Nó chỉ nói rằng đối tượng phải thực hiện giao diện IDisposable cung cấp phương thức Dispose trên đối tượng thực hiện giao diện.Vì vậy, để xử lý đối tượng, nó sẽ cần phải gọi phương thức Dispose trên đối tượng sẽ dọn dẹp và giải phóng các tài nguyên được sử dụng bởi đối tượng.

Hãy xem ví dụ này ..

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace BlogSamples 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      //Assume that Car is IDisposible. 
      using (Car myCar = new Car(1)) 
      { 
       myCar.Run(); 
      } 
     } 
    } 
} 

Compiler chuyển đổi sang mã trông như thế này ..

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace BlogSamples 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      //Declare myCar object with FullName of the type as seen in IL. 
      BlogSamples.Car myCar; 

      //Instantiate the object by calling the constructor, matching the flow of IL. 
      myCar = new Car(1); 

      try 
      { 
       myCar.Run(); 
      } 
      finally 
      { 
       if(myCar != null) 
        myCar.Dispose(); 
      } 
     } 
    } 
} 

Để hiểu làm thế nào một cách chính xác bằng cách sử dụng các công trình khối dưới mui xe, tôi khuyên bạn nên bạn đọc điều này blog-post.

http://www.ruchitsurati.net/index.php/2010/07/28/understanding-%E2%80%98using%E2%80%99-block-in-c/

+1

Trên thực tế, tôi muốn nói đó là một điều tốt mà MSDN không nói những gì xảy ra dưới mui xe. Một vài điều MSDN cung cấp chi tiết thực hiện mà không cần nhiều giải thích chi tiết thực hiện là gì, và những gì được yêu cầu (stack vs heap khi nói đến giá trị và kiểu tham chiếu sẽ là một ví dụ điển hình). Nó sẽ đẹp hơn trong một vài cách nếu tách chúng tốt hơn. Nếu nó ** cũng ** thực hiện chi tiết mà muốn được tốt đẹp, nhưng tôi thích có thông tin chi tiết văn bản quy phạm chi tiết. –

Các vấn đề liên quan