2009-04-01 26 views
13

Mã sau có hoạt động nếu tài nguyên không triển khai IDisposable không?Sẽ sử dụng công việc trên không?

T resource = new T(); 
    using (resource as IDisposable) 
    { 
    ... 
    } 
+1

nhưng ... tại sao bạn sẽ làm điều đó? –

+1

Tôi nghĩ rằng câu hỏi này là hợp lệ và tôi không hiểu tại sao sombody lại bình chọn nó. – alex

Trả lời

10

Vâng, nó sẽ làm việc, kiểm tra chạy thử này:

[TestMethod] 
public void TestMethod8() 
{ 
    using (new MyClass() as IDisposable) 
    { 
    } 
} 
public class MyClass { } 

Nó chỉ chạy mà không có bất kỳ vấn đề. Nếu lớp tương ứng thực hiện IDisposable nó sẽ gọi nó, nếu không nó vẫn sẽ làm việc/chạy :).

Cập nhật: Như những người khác đã nói, tôi cũng tự hỏi bạn đang sử dụng cách nào để sử dụng nó. Đoán của tôi là bạn có một cái gì đó giống như một nhà máy có thể nhận được các trường hợp từ các lớp khác nhau, có thể hoặc có thể không dùng một lần :).

1

Nếu "nó hoạt động" nghĩa là bạn sẽ gặp lỗi thời gian chạy? Không, bạn sẽ không.

1

Việc sử dụng điều này là gì? Lợi thế là gì? Lợi ích là gì?

Tuyên bố sử dụng sẽ đảm bảo rằng phương pháp Vứt bỏ được gọi, nhưng nếu đối tượng của bạn không triển khai IDisposable, tôi thấy không sử dụng làm điều này? Nó sẽ hoạt động (như trong, nó sẽ không ném ngoại lệ thời gian chạy và nó sẽ biên dịch), tôi đã thử nghiệm nó ở đây nhưng ...

Với mã bạn đã viết xuống, bạn thậm chí không thể sử dụng tài nguyên như là một IDisposable ...

+0

@Frederik được thêm vào câu trả lời của tôi: phỏng đoán của tôi là một nhà máy có thể giúp bạn có được các trường hợp từ các lớp khác nhau có thể hoặc không thể dùng một lần. – eglasius

16

Có. Một tuyên bố using kiểm tra xem nó đang được đưa ra null và tránh cố gắng gọi Dispose nếu có.

Từ phần 8.13 của C# 3 spec:

Một tuyên bố sử dụng được dịch sang ba phần: thu thập, sử dụng và xử lý. Việc sử dụng tài nguyên là được bao bọc hoàn toàn trong tuyên bố thử bao gồm mệnh đề cuối cùng. Điều khoản cuối cùng này xử lý tài nguyên . Nếu một tài nguyên rỗng là được mua lại, thì không có lệnh gọi là Vứt bỏ là được thực hiện và không có ngoại lệ nào được ném.

2

Nó sẽ hoạt động tốt, ngay cả khi không phải là cách tiếp cận "đúng" để xử lý tài nguyên. Các using Statment chỉ là cú pháp đường cho

IDisposable o = ...; 

try 
{ 
    // ... 
} 
finally 
{ 
    if (o != null) 
    o.Dispose(true); 
} 

Vì vậy, nếu o không bao giờ thực hiện IDisposable nó sẽ là null trong báo cáo kết quả using và nó sẽ cố gắng gọi Dispose trên đó.

+0

@Samuel thêm vào câu trả lời của tôi: tôi đoán là một nhà máy có thể giúp bạn có được các trường hợp từ các lớp khác nhau mà có thể hoặc không thể dùng một lần. – eglasius

2

Khi thử nghiệm mã, có vẻ như không dẫn đến bất kỳ lỗi biên dịch hoặc thời gian chạy nào.

Từ định nghĩa ngôn ngữ (xem phần 8.13): -

Nếu một nguồn tài nguyên vô được mua lại, sau đó không gọi để Vứt bỏ được thực hiện, và không ngoại lệ được ném.

Nếu loại này không thể chuyển đổi thành ID, thì mã được đóng gói trong khối sử dụng sẽ thực thi hoàn toàn tốt, hoạt động chính xác giống như khi bạn chưa đính kèm sử dụng khối.

Tóm lại, câu trả lời cho câu hỏi của bạn là có.

1

Nó có thể hữu ích khi loại thực hiện rõ ràng IDisposable trong trường hợp phương pháp Vứt bỏ không thể truy cập trực tiếp trên loại trừ khi loại được đúc thành IDisposable, Sử dụng ký tự an toàn và đảm bảo rằng gọi là. Trong hầu hết các trường hợp khi loại thực hiện một cách rõ ràng IDisposable, nó cung cấp các phương pháp như 'Đóng' mà lần lượt gọi Dispose

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