2011-07-03 34 views
5

Có lời khuyên trong C++: "Không bao giờ trả lại một tham chiếu đến một đối tượng địa phương", như được trích dẫn từ "C++ Primer":từ C++ đến C#: Không bao giờ trả về một tham chiếu đến một đối tượng cục bộ?

"Có một điều quan trọng quan trọng cần hiểu về việc trả về tham chiếu: Không bao giờ trả về một tham chiếu đến một biến cục bộ

"Khi một hàm hoàn thành, lưu trữ trong đó các đối tượng địa phương được cấp phát sẽ được giải phóng. Một tham chiếu đến một đối tượng cục bộ đề cập đến bộ nhớ không xác định sau khi hàm kết thúc. Hãy xem xét các chức năng sau:..

// Disaster: Function returns a reference to a local object 
const string &manip(const string& s) 
{ 
     string ret = s; 
     // transform ret in some way 
     return ret; // Wrong: Returning reference to a local object! 
} 

"Chức năng này sẽ thất bại tại thời gian chạy vì nó trả về một tham chiếu đến một đối tượng địa phương Khi chức năng kết thúc, lưu trữ, trong đó ret cư trú được trả tự do Giá trị trả lại đề cập đến bộ nhớ không còn có sẵn cho chương trình nữa. "

Câu hỏi: điều này vẫn áp dụng cho C#? hoặc nó không quan trọng như GC được giới thiệu?

+1

Tôi không đồng ý với "chức năng này sẽ thất bại tại thời gian chạy.". Nó * có thể * thất bại, và không an toàn. Nhưng trong nhiều trường hợp, lưu trữ sẽ có sẵn trong một thời gian sau khi trả lại, Thường làm cho loại vấn đề này khó gỡ lỗi. – abelenky

+1

abelenky là chính xác; không có gì đảm bảo rằng bất cứ điều gì mà sẽ thất bại, bao giờ hết. Nó không phải là một yêu cầu lưu trữ được "giải phóng", bất cứ điều gì có nghĩa là. Một chương trình thực hiện điều này có thể hoạt động theo cách bạn muốn - bạn có thể gặp may mắn - hoặc, nó có thể làm cho toàn bộ hệ thống bị treo, hoặc nó có thể xóa đĩa cứng của bạn. Nó có thể làm * bất cứ điều gì *. Xem http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794#6445794 để biết thêm suy nghĩ. –

Trả lời

5

Không thể quay trở lại tham chiếu đến các biến địa phương trong .NET

Xem: Why doesn't C# support the return of references?

Xem thêm: Ref returns and ref locals (Eric Lippert's Blog)

+0

Đây là phần sai gây hiểu lầm. Bạn không thể trả về * theo tham chiếu * nhưng bạn có thể trả về tham chiếu * a *.Tuy nhiên, tham chiếu này sẽ không đề cập đến một đối tượng địa phương. –

+0

@Konrad Rudolph: Huh? Trích dẫn: "tham chiếu đến biến cục bộ". Vì vậy, một cái gì đó như 'ref int Foo() {int x = 5; return ref x; } '. Đó là không thể. Và không có "đối tượng cục bộ" trong .NET, chỉ các biến cục bộ chứa tham chiếu đến các đối tượng do CLR quản lý. – dtb

+0

Tôi biết. Tôi vẫn nghĩ rằng điều này có thể được xây dựng rõ ràng hơn vì nó dễ dàng bị đánh lừa, thay vì chỉ liên kết ở nơi khác. Lưu ý rằng mặc dù những lời chỉ trích này tôi đã upvoted câu trả lời của bạn ... –

4

ngôn ngữ C# không cho phép điều đó. Trong C# có hai loại tham chiếu rất khác nhau:

1) Tham chiếu đến các lớp và "Loại tham chiếu" tương tự. Vì mục tiêu của chúng luôn được phân bổ trên đống nên tham chiếu sẽ luôn hợp lệ sau khi trả về.

2) Tham chiếu đến biến/tham số cục bộ. Được gọi là managed references trong CLR. Ví dụ:

void DoSomething(ref int i, ref object o) 

Bạn không thể khai báo kiểu trả về sử dụng loại tham chiếu này trong C# (Bản thân CLR cung cấp một số hỗ trợ hạn chế cho điều đó). Vì bạn chỉ có thể truyền chúng cho các hàm khác dưới dạng tham số, không thể lưu trữ chúng trong các trường và không thể trả về chúng, nên không thể giữ một trong các hàm đó sau khi hàm trả về. Vì vậy, một lần nữa sử dụng chúng là an toàn.

Về cơ bản trong C#, bạn chỉ có thể sử dụng chúng cho các tham số truyền theo tham chiếu. Lưu ý rằng bạn có thể có một ref đến biến loại tham chiếu (ref object o) nhưng không phải là tham chiếu đến tham chiếu ref ref int i.

Eric Lippert đăng tải một entry blog trên loại tài liệu tham khảo một vài ngày trước định chi tiết các vấn đề với các giá trị ref trở lại: Ref returns and ref locals

+0

cảm ơn CodeInChaos – athos

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