เหตุใด C # จึงมีทั้งข้อมูลอ้างอิงและอ้างอิง


18

C # มีoutและrefคำหลัก ทำไมต้องใช้ทั้งสองนี้ คำเตือน: ฉันไม่มีความรู้อย่างลึกซึ้งเกี่ยวกับ C #


3
ไม่มี cross-site ซ้ำซ้อนใน Stack Overflow หรือไม่
Peter Mortensen


2
คุณกำลังขอความแตกต่างระหว่างrefและout? หรือคุณกำลังถามว่าการใช้ข้อโต้แย้งแบบอ้างอิงref/ outเปรียบเทียบกับข้อโต้แย้งแบบมูลค่า (ไม่มีการแก้ไขพารามิเตอร์)? หรือทั้งคู่?
Jeppe Stig Nielsen

1
ฉันรู้สึกว่าคำถามนี้คล้ายกัน แต่ไม่ได้ซ้ำซ้อน - อย่างน้อยถ้ามันถูกนำมาจากมุมมองการออกแบบภาษา
jmoreno

คำตอบ:


32

การนำมาใช้อย่างชาญฉลาดนั้นเป็นสิ่งเดียวกัน แต่outสื่อสารสิ่งที่refไม่มี: คุณไม่สนใจอินพุต นี่หมายถึงบางสิ่งสำหรับคุณและเครื่องมือ ตัวอย่างเช่นคุณสามารถส่งผ่านตัวแปรที่ไม่มีค่าเริ่มต้นไปยังoutพารามิเตอร์และนั่นไม่ใช่ปัญหาไม่ว่าจะเกิดขึ้นที่ไหนและภายในฟังก์ชันที่คุณจำเป็นต้องกำหนดค่าให้กับoutพารามิเตอร์ก่อนที่จะส่งคืน ทั้งหมดมีrefค่า


10
Ref vs out มีความสำคัญมากกว่าคอมไพเลอร์มากกว่าสำหรับโปรแกรมเมอร์ คอมไพเลอร์มีหน้าที่ตรวจสอบให้แน่ใจว่าคุณไม่ได้อ่านตัวแปรก่อนที่มันจะถูกกำหนดค่าและoutให้มันเป็นวิธีที่ดีกว่าซึ่งตรงกับวิธีที่คุณต้องการจัดการกับตัวแปรในตอนแรก
Cort Ammon - Reinstate Monica

คุณช่วยอธิบายอย่างละเอียดเกี่ยวกับ: 'ออก' สื่อสารสิ่งที่ 'อ้างอิง' ไม่ได้
Neo

4
@ Neo: โดยทั่วไปสิ่งที่ฉันพูดในคำตอบ: มันสื่อสารว่าคุณไม่สนใจที่จะใช้สิ่งนี้สำหรับการป้อนข้อมูลและดังนั้นจึงปลอดภัยที่จะส่งค่าที่ไม่ได้กำหนดค่าเริ่มต้นให้กับoutparam เพราะฟังก์ชั่นที่รับไม่ได้อ่านจากมัน .
Mason Wheeler

@MasonWheeler สิ่งนี้อนุญาตให้ผู้ตรวจสอบ (และ / หรือบังคับใช้เมื่อสิ้นสุดการรับ) หรือไม่ Out เป็นเพียงคุณสมบัติภายใน
Random832

@ Random832: โรเบิร์ตโพสต์ภายใต้คำตอบของเขาให้ดูที่ Eric Lippert (คนรวบรวม C # เดิม) คุยเรื่องนี้ที่stackoverflow.com/q/2876315
Mason Wheeler

7

เพื่อให้เข้าใจคำหลักสองคำนี้คุณจะต้องเข้าใจว่าการส่งค่าโดยการอ้างอิงหมายถึงอะไร โดยพื้นฐานแล้วหมายความว่าหากคุณแก้ไขตัวแปรพารามิเตอร์ที่คุณส่งผ่านภายในเมธอดหรือฟังก์ชันตัวแปรนั้นจะเก็บค่าที่แก้ไขไว้เมื่อฟังก์ชันของคุณออก การประกาศพารามิเตอร์เป็นrefหรือoutบรรลุสิ่งนี้ในขณะที่ตัวแปรพารามิเตอร์ทั่วไปจะคงไว้ซึ่งค่าดั้งเดิมแม้ว่าคุณจะแก้ไขในฟังก์ชัน

ความแตกต่างเพียงอย่างเดียวระหว่างrefและoutคือoutไม่ต้องการให้คุณเริ่มต้นตัวแปรก่อนที่จะส่งผ่านไปยังฟังก์ชัน แต่refทำ ในขณะที่out ไม่ต้องการให้คุณกำหนดบางสิ่งบางอย่างให้กับตัวแปรภายในฟังก์ชัน แต่refไม่ได้


มีความแตกต่างที่เกี่ยวข้องกับความแปรปรวนหรือไม่
monocell

ดูคำตอบของ Eric Lippert ได้ที่stackoverflow.com/q/2876315
Robert Harvey

2

คุณถาม.

C # ออกไปข้างนอกแล้วทำไมต้องใช้ทั้งสองนี้ ฉันไม่มีความรู้เชิงลึกเกี่ยวกับ C # ทำไมต้องใช้พารามิเตอร์ out และ ref?

และคำตอบก็คือพวกเขาไม่ได้ต้องการ, java เช่นไม่มีและ VB มีเพียงอ้างอิง (และต้องการเพียงในการประกาศวิธีการ)

คุณสามารถเขียนโปรแกรมทั้งหมดได้อย่างง่ายดายโดยไม่ต้องใช้ทั้งโปรแกรม

มีอยู่เพราะเป็นประโยชน์ในบางครั้ง ซึ่งเป็นสาเหตุที่มีอยู่สองอย่างและไม่ใช่เพียงอย่างเดียว - เนื่องจากมีประโยชน์ในการสร้างความแตกต่างระหว่าง 'นี่คือบางสิ่งให้แก้ไขหากคุณต้องการ' และ 'ให้คุณค่าใหม่กับสิ่งนี้'

ภาษาอื่นมีลำดับความสำคัญต่างกันและอาจมีหรือไม่มีภาษาเหล่านี้หรือเทียบเท่า พวกเขาอาจไม่เห็นด้วยว่ามีประโยชน์หรือไม่และอาจตัดสินใจอย่างแข็งขันที่จะไม่ดำเนินการอย่างใดอย่างหนึ่ง


1

ที่แกนกลางทั้งสองrefและoutจัดเตรียมกลไกสำหรับการส่งที่อยู่ของตัวแปรไปยังวิธีการเพื่อให้สามารถอัปเดตได้ - การกำหนดให้กับrefหรือoutพารามิเตอร์จะปรับปรุงตัวแปรในบริบทของผู้โทร ความแตกต่างอยู่ที่ไหนในการค้ำประกัน: outรับประกันว่าตัวแปรจะได้รับการอัปเดตrefไม่ใช่

จากอีกด้านหนึ่งของการโทรมีความแตกต่างที่คล้ายกัน outพารามิเตอร์กับวิธีการของเราไม่รับประกันว่าจะมีอะไรที่เป็นประโยชน์เมื่อเดินทางมาถึงและจะต้องตั้งค่าในบางจุดขณะที่refพารามิเตอร์สามารถสันนิษฐานว่าจะมีค่าและเราไม่จำเป็นต้องทำเฉพาะอะไรกับมัน

ความแตกต่างนี้มีผลกระทบต่อการวิเคราะห์รหัสการสร้างและการเพิ่มประสิทธิภาพซึ่งในขณะที่เราไม่ได้ใช้เวลาส่วนใหญ่อย่างเห็นได้ชัดอาจมีผลกระทบบางอย่างเกี่ยวกับวิธีที่โปรแกรมของเราทำงาน ตัวสร้างรหัสสามารถเลื่อนการจัดสรรตัวแปรจนกว่าจะมีการโทรทันทีโดยทันทีเครื่องมือเพิ่มประสิทธิภาพอาจตัดสินใจว่าสามารถเรียงลำดับการดำเนินการบางอย่างได้อย่างมีประสิทธิภาพมากขึ้นตามสัญญาเป็นต้น

ในแง่ของการใช้งาน: ตามกฎทั่วไปฉันใช้outสำหรับสถานการณ์ที่ฉันไม่สนใจเกี่ยวกับเนื้อหาของตัวแปรเมื่อมันมาถึงเป็นพารามิเตอร์และrefเมื่อฉันทำ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.