Tại sao C # có cả out và ref?


18

C # có outreftừ khóa. Tại sao hai yêu cầu này? Tuyên bố miễn trừ trách nhiệm: Tôi không có kiến ​​thức sâu về C #.


3
Không có bản sao chéo trên Stack Overflow sao?
Peter Mortensen


2
Bạn đang yêu cầu sự khác biệt giữa refout? Hoặc bạn đang hỏi việc sử dụng các đối số theo tham chiếu ref/ outso với các đối số theo giá trị (không có sửa đổi cho tham số) là gì? Hoặc cả hai?
Jeppe Stig Nielsen

1
Tôi cảm thấy câu hỏi này tương tự, nhưng không hoàn toàn là một bản sao - ít nhất là nếu nó được lấy từ quan điểm thiết kế ngôn ngữ
jmoreno

Câu trả lời:


32

Thực hiện khôn ngoan, về cơ bản chúng giống nhau, nhưng outtruyền đạt một thứ refkhông: bạn không quan tâm đến đầu vào. Điều này có nghĩa là những điều nhất định với bạn và dụng cụ. Ví dụ: bạn có thể truyền một biến chưa được khởi tạo cho một outtham số và đó không phải là vấn đề, nếu không, và trong hàm bạn được yêu cầu gán giá trị cho outtham số trước khi trả về, trong khi không có yêu cầu phải làm gì tại Tất cả với một refgiá trị.


10
Ref vs out quan trọng hơn nhiều đối với trình biên dịch so với trình lập trình. Trình biên dịch có nghĩa vụ đảm bảo rằng bạn không đọc một biến trước khi nó được gán một giá trị và outcung cấp cho nó một cách để làm điều đó phù hợp hơn với cách bạn muốn xử lý các biến ở vị trí đầu tiên.
Cort Ammon - Tái lập lại

Bạn có thể vui lòng giải thích về: 'ra' truyền đạt một cái gì đó mà 'ref' không.
Neo

4
@Neo: Về cơ bản những gì tôi đã nói trong câu trả lời: Nó thông báo rằng bạn không quan tâm đến việc sử dụng cái này cho đầu vào, và do đó, nó an toàn để chuyển một giá trị chưa được khởi tạo cho một outparam vì hàm nhận được nó sẽ không đọc từ nó .
Mason Wheeler

@MasonWheeler Điều này có được phép (và / hoặc được thi hành ở đầu nhận) không? Out chỉ là một thuộc tính, trong nội bộ.
Random832

@ Random832: Như Robert đã đăng dưới câu trả lời của mình, hãy xem Eric Lippert (cựu biên dịch viên C #) thảo luận về điều này tại stackoverflow.com/q/2876315
Mason Wheeler

7

Để hiểu hai từ khóa này, bạn sẽ cần hiểu việc chuyển một giá trị bằng tham chiếu nghĩa là gì. Về cơ bản, điều đó có nghĩa là, nếu bạn sửa đổi biến tham số mà bạn truyền vào trong phương thức hoặc hàm, biến đó sẽ giữ lại giá trị đã sửa đổi của nó khi hàm của bạn thoát. Khai báo một tham số là refhoặc outthực hiện điều này, trong khi một biến tham số thông thường sẽ giữ nguyên giá trị ban đầu của nó, ngay cả khi bạn đã sửa đổi nó trong hàm.

Sự khác biệt duy nhất giữa refoutoutkhông yêu cầu bạn khởi tạo biến trước khi bạn chuyển nó vào hàm, nhưng refkhông; trong khi out không yêu cầu bạn gán một cái gì đó cho biến trong hàm, nhưng refkhông.


Không có sự khác biệt liên quan đến phương sai?
monocell

Xem câu trả lời của Eric Lippert trên stackoverflow.com/q/2876315
Robert Harvey

2

Bạn đã hỏi.

C # có ra và ref, tại sao hai cái này là bắt buộc. Tôi không có kiến ​​thức chuyên sâu về C #. Tại sao tham số out và ref là bắt buộc?

Và câu trả lời là họ không BẮT BUỘC, ví dụ java không có hoặc VB chỉ có ref (và chỉ yêu cầu nó trong khai báo phương thức).

Bạn có thể dễ dàng viết toàn bộ chương trình mà không cần sử dụng.

Chúng tồn tại bởi vì chúng đôi khi hữu ích. Đó là lý do tại sao có hai trong số họ chứ không chỉ một - bởi vì thật hữu ích khi phân biệt giữa 'đây là một cái gì đó, sửa đổi nó nếu bạn muốn' và 'cung cấp cho điều này một giá trị mới'.

Các ngôn ngữ khác có các ưu tiên khác nhau và do đó có thể hoặc không bao gồm những ngôn ngữ này hoặc tương đương. Họ thậm chí có thể không đồng ý về việc liệu có hữu ích hay không, và do đó có thể chủ động quyết định KHÔNG thực hiện cái này hay cái kia.


1

Tại cốt lõi của cả hai refoutcung cấp một cơ chế truyền địa chỉ của biến cho một phương thức để có thể cập nhật nó - gán cho refhoặc outtham số cập nhật biến trong ngữ cảnh của trình gọi. Trường hợp chúng khác nhau là trong các đảm bảo: outđảm bảo rằng biến sẽ được cập nhật, refkhông.

Từ phía bên kia của cuộc gọi có sự khác biệt tương tự. Một outtham số cho phương thức của chúng tôi không được đảm bảo có chứa bất cứ điều gì hữu ích khi đến và phải được đặt thành một giá trị tại một số điểm, trong khi một reftham số có thể được coi là có giá trị và chúng tôi không cần phải làm gì cụ thể với nó.

Sự khác biệt này có tác động đến phân tích, tạo và tối ưu hóa mã, trong khi hầu như không rõ ràng đối với chúng ta hầu hết thời gian, có thể có một số ảnh hưởng đến cách các chương trình của chúng tôi kết thúc hoạt động. Trình tạo mã có thể trì hoãn phân bổ biến cho đến trước cuộc gọi ngay lập tức, trình tối ưu hóa có thể quyết định nó có thể sắp xếp lại một số hoạt động hiệu quả hơn dựa trên hợp đồng, v.v.

Về mặt sử dụng: như một quy tắc chung tôi sử dụng outcho các tình huống mà tôi không quan tâm đến nội dung của biến khi nó đến dưới dạng tham số và refkhi tôi thực hiện.

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.