=============
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
มีการเขียนบางสิ่งบางอย่างก่อนที่จะอ่านอะไรบางอย่างจากn
n
ที่อนุญาตลำดับของเหตุการณ์นี้:
- ประกาศเขตข้อมูลประเภท
x
Animal
- ผ่านการ
x
เป็นพารามิเตอร์out
N
N
เขียนTiger
ลงในซึ่งเป็นนามแฝงสำหรับn
x
- ในอีกกระทู้มีคนเขียน
Turtle
ลงในx
ไฟล์.
N
ความพยายามที่จะอ่านเนื้อหาของn
และค้นพบในสิ่งที่คิดว่าเป็นตัวแปรประเภทTurtle
Mammal
เห็นได้ชัดว่าเราต้องการทำให้สิ่งนั้นผิดกฎหมาย
ข้อสรุปที่ 4 : out
ไม่สามารถสร้างพารามิเตอร์ให้ "ใหญ่ขึ้น" ได้
ข้อสรุปสุดท้าย : ทั้งref
มิได้out
พารามิเตอร์อาจแตกต่างกันประเภทของพวกเขา การทำอย่างอื่นคือการทำลายประเภทความปลอดภัยที่ตรวจสอบได้
หากปัญหาเหล่านี้อยู่ในความสนใจประเภททฤษฎีพื้นฐานที่คุณพิจารณาการอ่านชุดของฉันเกี่ยวกับวิธีการแปรปรวนและ contravariance ทำงานใน C # 4.0