=============
UPDATE: ฉันใช้คำตอบนี้เป็นพื้นฐานสำหรับรายการบล็อกนี้:
เหตุใดพารามิเตอร์ ref and out จึงไม่อนุญาตให้มีการเปลี่ยนแปลงประเภท
ดูหน้าบล็อกสำหรับความคิดเห็นเพิ่มเติมเกี่ยวกับปัญหานี้ ขอบคุณสำหรับคำถามที่ดี
=============
สมมติว่าคุณได้เรียนAnimal, Mammal, Reptile, Giraffe, TurtleและTigerมีความสัมพันธ์ที่ subclassing ที่เห็นได้ชัด
void M(ref Mammal m)ตอนนี้สมมติว่าคุณมีวิธีการ Mทั้งอ่านและเขียนmได้
คุณสามารถส่งตัวแปรประเภทAnimalไปยังM?
ไม่ตัวแปรนั้นอาจมี a Turtleแต่Mจะถือว่ามี แต่สัตว์เลี้ยงลูกด้วยนม A Turtleไม่ใช่Mammal.
ข้อสรุปที่ 1 : refไม่สามารถสร้างพารามิเตอร์ให้ "ใหญ่กว่า" ได้ (มีสัตว์มากกว่าสัตว์เลี้ยงลูกด้วยนมดังนั้นตัวแปรจึง "ใหญ่ขึ้น" เพราะสามารถบรรจุสิ่งของได้มากกว่า)
คุณสามารถส่งตัวแปรประเภทGiraffeไปยังM?
ไม่MสามารถเขียนถึงmและMอาจต้องการเขียนTigerลงในmไฟล์. ตอนนี้คุณได้ใส่Tigerตัวแปรซึ่งเป็นประเภทGiraffeจริงๆ
ข้อสรุปที่ 2 : refพารามิเตอร์ไม่สามารถทำให้ "เล็กลง" ได้
N(out Mammal n)ตอนนี้พิจารณา
คุณสามารถส่งตัวแปรประเภทGiraffeไปยังN?
ไม่NสามารถเขียนถึงnและNอาจต้องการเขียนไฟล์Tiger.
สรุป 3 : outพารามิเตอร์ไม่สามารถทำให้ "เล็กลง" ได้
คุณสามารถส่งตัวแปรประเภทAnimalไปยังN?
อืมมม
ทำไมไม่? Nอ่านไม่ออกnก็เขียนได้แค่นั้นใช่ไหม คุณเขียนTigerถึงตัวแปรประเภทAnimalและคุณพร้อมแล้วใช่ไหม?
ไม่ถูกต้อง. กฎไม่ใช่ " Nเขียนถึงได้เท่านั้นn"
กฎคือสั้น ๆ :
1) Nต้องเขียนถึงnก่อนNส่งคืนตามปกติ (หากNโยนการเดิมพันทั้งหมดจะปิด)
2) Nมีการเขียนบางสิ่งบางอย่างก่อนที่จะอ่านอะไรบางอย่างจากnn
ที่อนุญาตลำดับของเหตุการณ์นี้:
- ประกาศเขตข้อมูลประเภท
xAnimal
- ผ่านการ
xเป็นพารามิเตอร์outN
NเขียนTigerลงในซึ่งเป็นนามแฝงสำหรับnx
- ในอีกกระทู้มีคนเขียน
Turtleลงในxไฟล์.
Nความพยายามที่จะอ่านเนื้อหาของnและค้นพบในสิ่งที่คิดว่าเป็นตัวแปรประเภทTurtleMammal
เห็นได้ชัดว่าเราต้องการทำให้สิ่งนั้นผิดกฎหมาย
ข้อสรุปที่ 4 : outไม่สามารถสร้างพารามิเตอร์ให้ "ใหญ่ขึ้น" ได้
ข้อสรุปสุดท้าย : ทั้งrefมิได้outพารามิเตอร์อาจแตกต่างกันประเภทของพวกเขา การทำอย่างอื่นคือการทำลายประเภทความปลอดภัยที่ตรวจสอบได้
หากปัญหาเหล่านี้อยู่ในความสนใจประเภททฤษฎีพื้นฐานที่คุณพิจารณาการอ่านชุดของฉันเกี่ยวกับวิธีการแปรปรวนและ contravariance ทำงานใน C # 4.0