Mảng hoặc danh sách có được truyền theo mặc định bằng tham chiếu trong c # không?


84

Họ có? Hoặc để tăng tốc chương trình của tôi, tôi nên chuyển chúng bằng cách tham chiếu?


35
Để tăng tốc chương trình của mình, bạn nên (1) đặt các mục tiêu có ý nghĩa, (2) kiểm tra xem bạn đã đạt được mục tiêu chưa, (3) nếu chưa đạt, hãy sử dụng công cụ lập hồ sơ để tìm ra điều chậm nhất và (4 ) tối ưu hóa thứ chậm nhất.
Eric Lippert


3
@EricLippert Bình luận của bạn trả lời câu hỏi thực sự của OP tốt hơn nhiều so với bất kỳ câu trả lời nào đã đăng. Mọi người đều bị phân tâm bởi các kỹ thuật "chuyển tham chiếu theo giá trị" đến mức họ hoàn toàn bỏ qua câu hỏi thực sự về tối ưu hóa hiệu suất. Thật không may, OP đã truyền đạt nhu cầu của mình khá kém và các câu trả lời khác ít nhất sẽ giúp ích cho đám đông của Google.
Dan Bechard

"các câu trả lời khác ít nhất sẽ giúp ích cho đám đông Google" - họ sẽ làm được! :)
miki

Câu trả lời:


208

Các tài liệu tham khảo được truyền theo giá trị .

Mảng trong .NET là đối tượng trên heap, vì vậy bạn có một tham chiếu. Tham chiếu đó được chuyển bằng giá trị, nghĩa là người gọi sẽ nhìn thấy các thay đổi đối với nội dung của mảng, nhưng việc gán lại mảng sẽ không:

void Foo(int[] data) {
    data[0] = 1; // caller sees this
}
void Bar(int[] data) {
    data = new int[20]; // but not this
}

Nếu bạn thêm công cụ refsửa đổi, tham chiếu sẽ được chuyển bằng tham chiếu - và người gọi sẽ thấy một trong hai thay đổi ở trên.


28
Câu trả lời là đúng nhưng tôi rất ghét những người nói rằng "tham chiếu được chuyển theo giá trị". Nó nhầm lẫn vấn đề. Có, các tham chiếu (địa chỉ bộ nhớ) được chuyển theo giá trị nhưng đó không phải là câu hỏi.
WernerVA

9
@WernerVA Tôi quan tâm đến cách bạn nghĩ bạn sẽ diễn đạt theo cách khác mà vẫn đúngrõ ràng
Marc Gravell

2
Tôi sẽ không diễn đạt khác đi, có lẽ chỉ là một chút chi tiết hơn.
WernerVA

Điều này không trả lời phần tốc độ của câu hỏi. Bạn có thể thấy rõ rằng việc tối ưu hóa một bản sao tham chiếu sẽ hoàn toàn không đáng kể so với hàng trăm thao tác đắt tiền hơn đang diễn ra, nhưng OP đã hỏi điều này một cách cụ thể.
Dan Bechard

7
@Dan phần tốc độ vốn được liên kết với "nếu mảng được truyền theo giá trị - nghĩa là bản sao của nội dung mảng - nghĩa là cấp phát và bản sao của tất cả bộ nhớ". Vì nó là một tham chiếu được chuyển qua, không có câu hỏi về hiệu suất để trả lời - phần câu hỏi đó được đưa ra tranh luận và được trả lời tự động. Ngoại trừ bây giờ nó cũng được trả lời ở đây một cách rõ ràng trong các bình luận ...
Marc Gravell

9

Chúng được truyền bởi giá trị (cũng như tất cả các tham số không phải tham chiếu cũng như không tham chiếu ), nhưng giá trị một tham chiếu đến đối tượng, vì vậy chúng được truyền một cách hiệu quả bằng tham chiếu.


0

Có, chúng được chuyển theo tham chiếu theo mặc định trong C #. Tất cả các đối tượng trong C # đều là, ngoại trừ các kiểu giá trị. Nói chính xác hơn một chút, chúng được chuyển "bằng tham chiếu theo giá trị"; nghĩa là giá trị của biến mà bạn thấy trong các phương thức của mình là một tham chiếu đến đối tượng ban đầu được truyền vào. Đây là một điểm ngữ nghĩa nhỏ, nhưng đôi khi có thể quan trọng.


9
Tham chiếu được truyền theo giá trị; rất khác với "chúng được chuyển qua tham chiếu".
Marc Gravell

1
Điều này hoàn toàn trái ngược với sự thật. Trích dẫn bài đăng này từ John Skeet : "Theo mặc định, tất cả các tham số đều được chuyển theo giá trị trong C #. Các tham số chỉ được chuyển bằng tham chiếu nếu bạn bao gồm một cách rõ ràng một công cụ sửa đổi out hoặc ref. Tuy nhiên, bạn cần lưu ý rằng khi loại tham số là một kiểu tham chiếu, bạn đang truyền một tham chiếu chứ không phải một đối tượng thực tế ". Nó chỉ là tham chiếu (địa chỉ bộ nhớ) được truyền bởi giá trị.
alexlomba87 Ngày
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.